@indexnetwork/protocol 4.15.0-rc.357.1 → 4.16.1-rc.359.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 (105) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/contact/contact.inviter.d.ts.map +1 -1
  3. package/dist/contact/contact.inviter.js +12 -5
  4. package/dist/contact/contact.inviter.js.map +1 -1
  5. package/dist/index.d.ts +12 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +5 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/opportunity/delivery-card.cache.d.ts.map +1 -1
  10. package/dist/opportunity/delivery-card.cache.js +7 -3
  11. package/dist/opportunity/delivery-card.cache.js.map +1 -1
  12. package/dist/opportunity/discriminator/discriminator.adjustments.d.ts +22 -15
  13. package/dist/opportunity/discriminator/discriminator.adjustments.d.ts.map +1 -1
  14. package/dist/opportunity/discriminator/discriminator.adjustments.js +39 -20
  15. package/dist/opportunity/discriminator/discriminator.adjustments.js.map +1 -1
  16. package/dist/opportunity/feed/feed.categorizer.d.ts.map +1 -1
  17. package/dist/opportunity/feed/feed.categorizer.js +6 -0
  18. package/dist/opportunity/feed/feed.categorizer.js.map +1 -1
  19. package/dist/opportunity/feed/feed.graph.d.ts +2 -0
  20. package/dist/opportunity/feed/feed.graph.d.ts.map +1 -1
  21. package/dist/opportunity/feed/feed.graph.js +53 -28
  22. package/dist/opportunity/feed/feed.graph.js.map +1 -1
  23. package/dist/opportunity/feed/feed.state.d.ts +3 -1
  24. package/dist/opportunity/feed/feed.state.d.ts.map +1 -1
  25. package/dist/opportunity/feed/feed.state.js.map +1 -1
  26. package/dist/opportunity/opportunity.claim-safety.d.ts +25 -0
  27. package/dist/opportunity/opportunity.claim-safety.d.ts.map +1 -0
  28. package/dist/opportunity/opportunity.claim-safety.js +89 -0
  29. package/dist/opportunity/opportunity.claim-safety.js.map +1 -0
  30. package/dist/opportunity/opportunity.discover.d.ts.map +1 -1
  31. package/dist/opportunity/opportunity.discover.js +6 -1
  32. package/dist/opportunity/opportunity.discover.js.map +1 -1
  33. package/dist/opportunity/opportunity.evaluator.d.ts.map +1 -1
  34. package/dist/opportunity/opportunity.evaluator.js +13 -8
  35. package/dist/opportunity/opportunity.evaluator.js.map +1 -1
  36. package/dist/opportunity/opportunity.graph.d.ts +36 -0
  37. package/dist/opportunity/opportunity.graph.d.ts.map +1 -1
  38. package/dist/opportunity/opportunity.graph.js +177 -18
  39. package/dist/opportunity/opportunity.graph.js.map +1 -1
  40. package/dist/opportunity/opportunity.persist.d.ts +8 -1
  41. package/dist/opportunity/opportunity.persist.d.ts.map +1 -1
  42. package/dist/opportunity/opportunity.persist.js +23 -2
  43. package/dist/opportunity/opportunity.persist.js.map +1 -1
  44. package/dist/opportunity/opportunity.presentation-cache.d.ts +7 -0
  45. package/dist/opportunity/opportunity.presentation-cache.d.ts.map +1 -0
  46. package/dist/opportunity/opportunity.presentation-cache.js +15 -0
  47. package/dist/opportunity/opportunity.presentation-cache.js.map +1 -0
  48. package/dist/opportunity/opportunity.presentation.d.ts.map +1 -1
  49. package/dist/opportunity/opportunity.presentation.js +8 -5
  50. package/dist/opportunity/opportunity.presentation.js.map +1 -1
  51. package/dist/opportunity/opportunity.presenter.d.ts +4 -4
  52. package/dist/opportunity/opportunity.presenter.d.ts.map +1 -1
  53. package/dist/opportunity/opportunity.presenter.js +55 -14
  54. package/dist/opportunity/opportunity.presenter.js.map +1 -1
  55. package/dist/opportunity/opportunity.safe-presentation.d.ts +1 -1
  56. package/dist/opportunity/opportunity.safe-presentation.d.ts.map +1 -1
  57. package/dist/opportunity/opportunity.safe-presentation.js +22 -9
  58. package/dist/opportunity/opportunity.safe-presentation.js.map +1 -1
  59. package/dist/opportunity/opportunity.state.d.ts +3 -0
  60. package/dist/opportunity/opportunity.state.d.ts.map +1 -1
  61. package/dist/opportunity/opportunity.state.js.map +1 -1
  62. package/dist/opportunity/opportunity.tools.d.ts +1 -17
  63. package/dist/opportunity/opportunity.tools.d.ts.map +1 -1
  64. package/dist/opportunity/opportunity.tools.js +32 -2
  65. package/dist/opportunity/opportunity.tools.js.map +1 -1
  66. package/dist/shared/agent/model.config.d.ts +5 -0
  67. package/dist/shared/agent/model.config.d.ts.map +1 -1
  68. package/dist/shared/agent/model.config.js +1 -0
  69. package/dist/shared/agent/model.config.js.map +1 -1
  70. package/dist/shared/hyde/hyde.documents.d.ts +10 -0
  71. package/dist/shared/hyde/hyde.documents.d.ts.map +1 -0
  72. package/dist/shared/hyde/hyde.documents.js +50 -0
  73. package/dist/shared/hyde/hyde.documents.js.map +1 -0
  74. package/dist/shared/hyde/hyde.env.d.ts +9 -0
  75. package/dist/shared/hyde/hyde.env.d.ts.map +1 -0
  76. package/dist/shared/hyde/hyde.env.js +10 -0
  77. package/dist/shared/hyde/hyde.env.js.map +1 -0
  78. package/dist/shared/hyde/hyde.frame.d.ts +151 -0
  79. package/dist/shared/hyde/hyde.frame.d.ts.map +1 -0
  80. package/dist/shared/hyde/hyde.frame.js +108 -0
  81. package/dist/shared/hyde/hyde.frame.js.map +1 -0
  82. package/dist/shared/hyde/hyde.generator.d.ts +23 -11
  83. package/dist/shared/hyde/hyde.generator.d.ts.map +1 -1
  84. package/dist/shared/hyde/hyde.generator.js +50 -21
  85. package/dist/shared/hyde/hyde.generator.js.map +1 -1
  86. package/dist/shared/hyde/hyde.graph.d.ts +58 -17
  87. package/dist/shared/hyde/hyde.graph.d.ts.map +1 -1
  88. package/dist/shared/hyde/hyde.graph.js +333 -89
  89. package/dist/shared/hyde/hyde.graph.js.map +1 -1
  90. package/dist/shared/hyde/hyde.state.d.ts +19 -2
  91. package/dist/shared/hyde/hyde.state.d.ts.map +1 -1
  92. package/dist/shared/hyde/hyde.state.js +23 -3
  93. package/dist/shared/hyde/hyde.state.js.map +1 -1
  94. package/dist/shared/hyde/hyde.validator.d.ts +79 -0
  95. package/dist/shared/hyde/hyde.validator.d.ts.map +1 -0
  96. package/dist/shared/hyde/hyde.validator.js +49 -0
  97. package/dist/shared/hyde/hyde.validator.js.map +1 -0
  98. package/dist/shared/hyde/lens.inferrer.d.ts +190 -12
  99. package/dist/shared/hyde/lens.inferrer.d.ts.map +1 -1
  100. package/dist/shared/hyde/lens.inferrer.js +93 -38
  101. package/dist/shared/hyde/lens.inferrer.js.map +1 -1
  102. package/dist/shared/interfaces/database.interface.d.ts +46 -2
  103. package/dist/shared/interfaces/database.interface.d.ts.map +1 -1
  104. package/dist/shared/interfaces/database.interface.js.map +1 -1
  105. package/package.json +2 -1
@@ -1,3 +1,11 @@
1
+ /**
2
+ * Lens Inferrer Agent: analyzes source text (intent or query) with optional
3
+ * profile context and infers 1-N search lenses, each tagged with a target corpus.
4
+ * Replaces the hardcoded HydeStrategy enum and regex-based selectStrategiesFromQuery.
5
+ */
6
+ import type { BaseLanguageModelInput } from '@langchain/core/language_models/base';
7
+ import { z } from 'zod';
8
+ import { type HydeSourceFrame } from './hyde.frame.js';
1
9
  export type HydeTargetCorpus = 'profiles' | 'intents' | 'premises';
2
10
  /** A single inferred lens — a search perspective the LLM decided is relevant. */
3
11
  export interface Lens {
@@ -15,23 +23,193 @@ export interface LensInferenceInput {
15
23
  profileContext?: string;
16
24
  /** Maximum number of lenses to infer (default 3). */
17
25
  maxLenses?: number;
26
+ /** Use the source-grounded frame-v1 inference path. */
27
+ frameConstrained?: boolean;
18
28
  }
19
29
  export interface LensInferenceOutput {
20
30
  lenses: Lens[];
31
+ /** Sanitized source frame, present only for frame-constrained inference. */
32
+ sourceFrame?: HydeSourceFrame;
21
33
  }
22
- /**
23
- * Infers search lenses from source text and optional profile context.
24
- * Each lens represents a search perspective tagged with a target corpus
25
- * (profiles or intents) for downstream HyDE document generation.
26
- */
34
+ /** Source-grounded system prompt used only by frame extraction. */
35
+ export declare const FRAME_SYSTEM_PROMPT = "You extract a source-grounded frame for semantic retrieval from sourceText alone.\n\nSource-frame rules:\n- Extract evidence ONLY from sourceText.\n- Every frame element must include an evidence field copied as an exact substring of sourceText.\n- sourceRoles describe roles held or offered by the source side.\n- sourceRoles and counterpartRoles MUST use generic lower-case role labels only (for example, \"founder\", \"investor\", or \"technical advisor\"). Never put a person, organization, product, location, time, number, credential, or exclusivity detail in a role label.\n- counterpartRoles describe reciprocal or complementary target roles. A generic role may be inferred, but its evidence must be an exact sourceText span that supports the inference.\n- hardConstraints contain only explicit constraints and classify each as location, time, numeric, credential, organization, exclusivity, or other.\n- namedEntities contain only proper names explicitly present in sourceText and classify each as person, organization, product, location, event, or other.\n- domainVocabulary contains source domain terms worth preserving.";
36
+ /** Structured-output schema used only by source-frame extraction. */
37
+ export declare const FrameResponseSchema: z.ZodObject<{
38
+ sourceFrame: z.ZodObject<{
39
+ sourceRoles: z.ZodArray<z.ZodObject<{
40
+ role: z.ZodString;
41
+ evidence: z.ZodString;
42
+ }, "strip", z.ZodTypeAny, {
43
+ role: string;
44
+ evidence: string;
45
+ }, {
46
+ role: string;
47
+ evidence: string;
48
+ }>, "many">;
49
+ counterpartRoles: z.ZodArray<z.ZodObject<{
50
+ role: z.ZodString;
51
+ evidence: z.ZodString;
52
+ }, "strip", z.ZodTypeAny, {
53
+ role: string;
54
+ evidence: string;
55
+ }, {
56
+ role: string;
57
+ evidence: string;
58
+ }>, "many">;
59
+ hardConstraints: z.ZodArray<z.ZodObject<{
60
+ type: z.ZodEnum<["location", "time", "numeric", "credential", "organization", "exclusivity", "other"]>;
61
+ value: z.ZodString;
62
+ evidence: z.ZodString;
63
+ }, "strip", z.ZodTypeAny, {
64
+ value: string;
65
+ type: "location" | "time" | "numeric" | "credential" | "organization" | "exclusivity" | "other";
66
+ evidence: string;
67
+ }, {
68
+ value: string;
69
+ type: "location" | "time" | "numeric" | "credential" | "organization" | "exclusivity" | "other";
70
+ evidence: string;
71
+ }>, "many">;
72
+ namedEntities: z.ZodArray<z.ZodObject<{
73
+ type: z.ZodEnum<["person", "organization", "product", "location", "event", "other"]>;
74
+ name: z.ZodString;
75
+ evidence: z.ZodString;
76
+ }, "strip", z.ZodTypeAny, {
77
+ type: "location" | "event" | "organization" | "other" | "person" | "product";
78
+ name: string;
79
+ evidence: string;
80
+ }, {
81
+ type: "location" | "event" | "organization" | "other" | "person" | "product";
82
+ name: string;
83
+ evidence: string;
84
+ }>, "many">;
85
+ domainVocabulary: z.ZodArray<z.ZodObject<{
86
+ term: z.ZodString;
87
+ evidence: z.ZodString;
88
+ }, "strip", z.ZodTypeAny, {
89
+ evidence: string;
90
+ term: string;
91
+ }, {
92
+ evidence: string;
93
+ term: string;
94
+ }>, "many">;
95
+ }, "strip", z.ZodTypeAny, {
96
+ sourceRoles: {
97
+ role: string;
98
+ evidence: string;
99
+ }[];
100
+ counterpartRoles: {
101
+ role: string;
102
+ evidence: string;
103
+ }[];
104
+ hardConstraints: {
105
+ value: string;
106
+ type: "location" | "time" | "numeric" | "credential" | "organization" | "exclusivity" | "other";
107
+ evidence: string;
108
+ }[];
109
+ namedEntities: {
110
+ type: "location" | "event" | "organization" | "other" | "person" | "product";
111
+ name: string;
112
+ evidence: string;
113
+ }[];
114
+ domainVocabulary: {
115
+ evidence: string;
116
+ term: string;
117
+ }[];
118
+ }, {
119
+ sourceRoles: {
120
+ role: string;
121
+ evidence: string;
122
+ }[];
123
+ counterpartRoles: {
124
+ role: string;
125
+ evidence: string;
126
+ }[];
127
+ hardConstraints: {
128
+ value: string;
129
+ type: "location" | "time" | "numeric" | "credential" | "organization" | "exclusivity" | "other";
130
+ evidence: string;
131
+ }[];
132
+ namedEntities: {
133
+ type: "location" | "event" | "organization" | "other" | "person" | "product";
134
+ name: string;
135
+ evidence: string;
136
+ }[];
137
+ domainVocabulary: {
138
+ evidence: string;
139
+ term: string;
140
+ }[];
141
+ }>;
142
+ }, "strip", z.ZodTypeAny, {
143
+ sourceFrame: {
144
+ sourceRoles: {
145
+ role: string;
146
+ evidence: string;
147
+ }[];
148
+ counterpartRoles: {
149
+ role: string;
150
+ evidence: string;
151
+ }[];
152
+ hardConstraints: {
153
+ value: string;
154
+ type: "location" | "time" | "numeric" | "credential" | "organization" | "exclusivity" | "other";
155
+ evidence: string;
156
+ }[];
157
+ namedEntities: {
158
+ type: "location" | "event" | "organization" | "other" | "person" | "product";
159
+ name: string;
160
+ evidence: string;
161
+ }[];
162
+ domainVocabulary: {
163
+ evidence: string;
164
+ term: string;
165
+ }[];
166
+ };
167
+ }, {
168
+ sourceFrame: {
169
+ sourceRoles: {
170
+ role: string;
171
+ evidence: string;
172
+ }[];
173
+ counterpartRoles: {
174
+ role: string;
175
+ evidence: string;
176
+ }[];
177
+ hardConstraints: {
178
+ value: string;
179
+ type: "location" | "time" | "numeric" | "credential" | "organization" | "exclusivity" | "other";
180
+ evidence: string;
181
+ }[];
182
+ namedEntities: {
183
+ type: "location" | "event" | "organization" | "other" | "person" | "product";
184
+ name: string;
185
+ evidence: string;
186
+ }[];
187
+ domainVocabulary: {
188
+ evidence: string;
189
+ term: string;
190
+ }[];
191
+ };
192
+ }>;
193
+ type ModelInput = BaseLanguageModelInput;
194
+ /** Minimal structured model contract used for deterministic injection in tests. */
195
+ export interface LensStructuredModel {
196
+ invoke(input: ModelInput, config?: {
197
+ signal?: AbortSignal;
198
+ }): Promise<unknown>;
199
+ }
200
+ export interface LensInferrerOptions {
201
+ legacyModel?: LensStructuredModel;
202
+ frameModel?: LensStructuredModel;
203
+ }
204
+ /** Infers search lenses from source text and optional profile context. */
27
205
  export declare class LensInferrer {
28
- private model;
29
- /**
30
- * Infer search lenses from source text and optional profile context.
31
- *
32
- * @param input - Source text, optional profile context, optional max lenses
33
- * @returns Array of inferred lenses with corpus tags; empty array on failure
34
- */
206
+ private legacyModel?;
207
+ private frameModel?;
208
+ constructor(options?: LensInferrerOptions);
209
+ private getLegacyModel;
210
+ private getFrameModel;
211
+ /** Infer search lenses while preserving the legacy path unless explicitly enabled. */
35
212
  infer(input: LensInferenceInput): Promise<LensInferenceOutput>;
36
213
  }
214
+ export {};
37
215
  //# sourceMappingURL=lens.inferrer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lens.inferrer.d.ts","sourceRoot":"/","sources":["shared/hyde/lens.inferrer.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC;AAEnE,iFAAiF;AACjF,MAAM,WAAW,IAAI;IACnB,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,MAAM,EAAE,gBAAgB,CAAC;IACzB,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,IAAI,EAAE,CAAC;CAChB;AA4BD;;;;GAIG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAEV;IAEH;;;;;OAKG;IAEG,KAAK,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAoCrE"}
1
+ {"version":3,"file":"lens.inferrer.d.ts","sourceRoot":"/","sources":["shared/hyde/lens.inferrer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAEnF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,OAAO,EAAkD,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvG,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC;AAEnE,iFAAiF;AACjF,MAAM,WAAW,IAAI;IACnB,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,MAAM,EAAE,gBAAgB,CAAC;IACzB,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,IAAI,EAAE,CAAC;IACf,4EAA4E;IAC5E,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAkBD,mEAAmE;AACnE,eAAO,MAAM,mBAAmB,8mCAUkC,CAAC;AAYnE,qEAAqE;AACrE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE9B,CAAC;AAEH,KAAK,UAAU,GAAG,sBAAsB,CAAC;AAEzC,mFAAmF;AACnF,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAChF;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,UAAU,CAAC,EAAE,mBAAmB,CAAC;CAClC;AAID,0EAA0E;AAC1E,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAC,CAAsB;IAC1C,OAAO,CAAC,UAAU,CAAC,CAAsB;gBAE7B,OAAO,GAAE,mBAAwB;IAQ7C,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,aAAa;IAOrB,sFAAsF;IAEhF,KAAK,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;CA8ErE"}
@@ -7,17 +7,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
- /**
11
- * Lens Inferrer Agent: analyzes source text (intent or query) with optional
12
- * profile context and infers 1-N search lenses, each tagged with a target corpus.
13
- * Replaces the hardcoded HydeStrategy enum and regex-based selectStrategiesFromQuery.
14
- */
15
10
  import { HumanMessage, SystemMessage } from '@langchain/core/messages';
16
11
  import { z } from 'zod';
17
- import { Timed } from "../observability/performance.js";
18
- import { protocolLogger } from '../observability/protocol.logger.js';
19
12
  import { createStructuredModel } from "../agent/model.config.js";
20
13
  import { invokeWithAbortSignal } from "../agent/model-signal.js";
14
+ import { protocolLogger } from '../observability/protocol.logger.js';
15
+ import { Timed } from "../observability/performance.js";
16
+ import { HydeSourceFrameSchema, sanitizeHydeSourceFrame } from './hyde.frame.js';
21
17
  const SYSTEM_PROMPT = `You analyze goals and search queries to identify the most relevant perspectives for finding matching people in a professional network.
22
18
 
23
19
  For each perspective you identify, specify:
@@ -33,37 +29,60 @@ Guidelines:
33
29
  - Use "profiles" when looking for a type of person (expert, advisor, leader). Use "intents" when looking for a complementary goal or need (someone raising, someone hiring, someone seeking collaboration). Use "premises" when looking for someone whose identity, values, or worldview aligns — stable traits rather than transient goals.
34
30
  - Always include at least one "profiles" perspective when the source describes a need that a specific type of professional could fulfill. Most intents benefit from profile-based discovery.
35
31
  - LOCATION AWARENESS: When the source text or user context mentions a specific location (city, region, country), incorporate it into lens descriptions. For example, "investors in San Francisco" should produce a lens like "SF-based early-stage investor" rather than just "early-stage investor". This helps the hypothetical document generator produce location-specific search documents, improving retrieval quality.`;
32
+ /** Source-grounded system prompt used only by frame extraction. */
33
+ export const FRAME_SYSTEM_PROMPT = `You extract a source-grounded frame for semantic retrieval from sourceText alone.
34
+
35
+ Source-frame rules:
36
+ - Extract evidence ONLY from sourceText.
37
+ - Every frame element must include an evidence field copied as an exact substring of sourceText.
38
+ - sourceRoles describe roles held or offered by the source side.
39
+ - sourceRoles and counterpartRoles MUST use generic lower-case role labels only (for example, "founder", "investor", or "technical advisor"). Never put a person, organization, product, location, time, number, credential, or exclusivity detail in a role label.
40
+ - counterpartRoles describe reciprocal or complementary target roles. A generic role may be inferred, but its evidence must be an exact sourceText span that supports the inference.
41
+ - hardConstraints contain only explicit constraints and classify each as location, time, numeric, credential, organization, exclusivity, or other.
42
+ - namedEntities contain only proper names explicitly present in sourceText and classify each as person, organization, product, location, event, or other.
43
+ - domainVocabulary contains source domain terms worth preserving.`;
44
+ const lensSchema = z.object({
45
+ label: z.string().describe('Specific description of the search perspective'),
46
+ corpus: z.enum(['profiles', 'intents', 'premises']).describe('Search user profiles, user intents, or user premises (identity/values)'),
47
+ reasoning: z.string().describe('Why this perspective is relevant'),
48
+ });
36
49
  const responseFormat = z.object({
37
- lenses: z.array(z.object({
38
- label: z.string().describe('Specific description of the search perspective'),
39
- corpus: z.enum(['profiles', 'intents', 'premises']).describe('Search user profiles, user intents, or user premises (identity/values)'),
40
- reasoning: z.string().describe('Why this perspective is relevant'),
41
- })).min(1).max(5).describe('Inferred search lenses'),
50
+ lenses: z.array(lensSchema).min(1).max(5).describe('Inferred search lenses'),
51
+ });
52
+ /** Structured-output schema used only by source-frame extraction. */
53
+ export const FrameResponseSchema = z.object({
54
+ sourceFrame: HydeSourceFrameSchema,
42
55
  });
43
56
  const logger = protocolLogger("LensInferrer");
44
- /**
45
- * Infers search lenses from source text and optional profile context.
46
- * Each lens represents a search perspective tagged with a target corpus
47
- * (profiles or intents) for downstream HyDE document generation.
48
- */
57
+ /** Infers search lenses from source text and optional profile context. */
49
58
  export class LensInferrer {
50
- constructor() {
51
- this.model = createStructuredModel("lensInferrer", responseFormat, {
59
+ constructor(options = {}) {
60
+ // Preserve legacy construction behavior in production. Frame-only model
61
+ // injection deliberately avoids constructing a provider-backed legacy model.
62
+ this.legacyModel = options.legacyModel
63
+ ?? (options.frameModel ? undefined : createStructuredModel("lensInferrer", responseFormat, { name: "lens_inferrer" }));
64
+ this.frameModel = options.frameModel;
65
+ }
66
+ getLegacyModel() {
67
+ this.legacyModel ?? (this.legacyModel = createStructuredModel("lensInferrer", responseFormat, {
52
68
  name: "lens_inferrer",
53
- });
69
+ }));
70
+ return this.legacyModel;
54
71
  }
55
- /**
56
- * Infer search lenses from source text and optional profile context.
57
- *
58
- * @param input - Source text, optional profile context, optional max lenses
59
- * @returns Array of inferred lenses with corpus tags; empty array on failure
60
- */
72
+ getFrameModel() {
73
+ this.frameModel ?? (this.frameModel = createStructuredModel("lensInferrer", FrameResponseSchema, {
74
+ name: "lens_inferrer_frame_v1",
75
+ }));
76
+ return this.frameModel;
77
+ }
78
+ /** Infer search lenses while preserving the legacy path unless explicitly enabled. */
61
79
  async infer(input) {
62
- const { sourceText, profileContext, maxLenses = 3 } = input;
80
+ const { sourceText, profileContext, maxLenses = 3, frameConstrained = false } = input;
63
81
  logger.verbose('Inferring lenses', {
64
82
  sourceTextLength: sourceText.length,
65
83
  hasProfileContext: !!profileContext,
66
84
  maxLenses,
85
+ frameConstrained,
67
86
  });
68
87
  let humanPrompt = `Identify up to ${maxLenses} search perspectives for finding relevant matches.\n\nSource: "${sourceText}"`;
69
88
  if (profileContext) {
@@ -73,20 +92,56 @@ export class LensInferrer {
73
92
  new SystemMessage(SYSTEM_PROMPT),
74
93
  new HumanMessage(humanPrompt),
75
94
  ];
76
- try {
77
- const result = await invokeWithAbortSignal(this.model, messages);
78
- const parsed = responseFormat.parse(result);
79
- const lenses = parsed.lenses.slice(0, maxLenses);
80
- logger.verbose('Lenses inferred', {
81
- count: lenses.length,
82
- lenses: lenses.map(l => ({ label: l.label, corpus: l.corpus })),
83
- });
84
- return { lenses };
95
+ if (!frameConstrained) {
96
+ try {
97
+ const result = await invokeWithAbortSignal(this.getLegacyModel(), messages);
98
+ const parsed = responseFormat.parse(result);
99
+ const lenses = parsed.lenses.slice(0, maxLenses);
100
+ logger.verbose('Lenses inferred', {
101
+ count: lenses.length,
102
+ lenses: lenses.map(l => ({ label: l.label, corpus: l.corpus })),
103
+ });
104
+ return { lenses };
105
+ }
106
+ catch (error) {
107
+ logger.error('Lens inference failed', { error });
108
+ return { lenses: [] };
109
+ }
85
110
  }
86
- catch (error) {
87
- logger.error('Lens inference failed', { error });
111
+ const frameMessages = [
112
+ new SystemMessage(FRAME_SYSTEM_PROMPT),
113
+ new HumanMessage(`Extract the source frame.\n\nSource: "${sourceText}"`),
114
+ ];
115
+ const lensPromise = (async () => {
116
+ const result = await invokeWithAbortSignal(this.getLegacyModel(), messages);
117
+ return responseFormat.parse(result).lenses.slice(0, maxLenses);
118
+ })();
119
+ const framePromise = (async () => {
120
+ const result = await invokeWithAbortSignal(this.getFrameModel(), frameMessages);
121
+ const parsed = FrameResponseSchema.parse(result);
122
+ return sanitizeHydeSourceFrame(sourceText, parsed.sourceFrame);
123
+ })();
124
+ const [lensResult, frameResult] = await Promise.allSettled([lensPromise, framePromise]);
125
+ if (lensResult.status === 'rejected') {
126
+ logger.error('Lens inference failed', { error: lensResult.reason });
88
127
  return { lenses: [] };
89
128
  }
129
+ const lenses = lensResult.value;
130
+ logger.verbose('Frame-constrained lenses inferred', { count: lenses.length });
131
+ if (frameResult.status === 'rejected') {
132
+ logger.error('Source frame extraction failed', { error: frameResult.reason });
133
+ return {
134
+ lenses,
135
+ sourceFrame: {
136
+ sourceRoles: [],
137
+ counterpartRoles: [],
138
+ hardConstraints: [],
139
+ namedEntities: [],
140
+ domainVocabulary: [],
141
+ },
142
+ };
143
+ }
144
+ return { lenses, sourceFrame: frameResult.value };
90
145
  }
91
146
  }
92
147
  __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"lens.inferrer.js","sourceRoot":"/","sources":["shared/hyde/lens.inferrer.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Lens Inferrer Agent: analyzes source text (intent or query) with optional\n * profile context and infers 1-N search lenses, each tagged with a target corpus.\n * Replaces the hardcoded HydeStrategy enum and regex-based selectStrategiesFromQuery.\n */\nimport { HumanMessage, SystemMessage } from '@langchain/core/messages';\nimport { z } from 'zod';\nimport { Timed } from \"../observability/performance.js\";\nimport { protocolLogger } from '../observability/protocol.logger.js';\nimport { createStructuredModel } from \"../agent/model.config.js\";\nimport { invokeWithAbortSignal } from \"../agent/model-signal.js\";\n\nexport type HydeTargetCorpus = 'profiles' | 'intents' | 'premises';\n\n/** A single inferred lens — a search perspective the LLM decided is relevant. */\nexport interface Lens {\n /** Free-text description (e.g. \"crypto infrastructure VC\"). */\n label: string;\n /** Which vector index to search: user profiles or user intents. */\n corpus: HydeTargetCorpus;\n /** Why this perspective is relevant (for logging/trace). */\n reasoning: string;\n}\n\nexport interface LensInferenceInput {\n /** Intent payload or search query. */\n sourceText: string;\n /** User's profile summary for domain context (optional). */\n profileContext?: string;\n /** Maximum number of lenses to infer (default 3). */\n maxLenses?: number;\n}\n\nexport interface LensInferenceOutput {\n lenses: Lens[];\n}\n\nconst SYSTEM_PROMPT = `You analyze goals and search queries to identify the most relevant perspectives for finding matching people in a professional network.\n\nFor each perspective you identify, specify:\n1. A clear, specific description of who or what to search for\n2. Whether to search \"profiles\" (user bios, expertise, backgrounds), \"intents\" (stated goals, needs, aspirations), or \"premises\" (identity assertions, values, worldview)\n3. A brief reason why this perspective is relevant\n\nGuidelines:\n- Be specific and domain-aware. \"early-stage crypto infrastructure investor\" is better than \"investor\".\n- Consider both sides: who can help the person AND whose goals complement theirs.\n- When user context is provided, tailor perspectives to their domain (e.g. a DePIN founder searching for \"investors\" needs crypto-native infra investors specifically).\n- Generate only perspectives that add distinct search value — don't repeat similar angles.\n- Use \"profiles\" when looking for a type of person (expert, advisor, leader). Use \"intents\" when looking for a complementary goal or need (someone raising, someone hiring, someone seeking collaboration). Use \"premises\" when looking for someone whose identity, values, or worldview aligns — stable traits rather than transient goals.\n- Always include at least one \"profiles\" perspective when the source describes a need that a specific type of professional could fulfill. Most intents benefit from profile-based discovery.\n- LOCATION AWARENESS: When the source text or user context mentions a specific location (city, region, country), incorporate it into lens descriptions. For example, \"investors in San Francisco\" should produce a lens like \"SF-based early-stage investor\" rather than just \"early-stage investor\". This helps the hypothetical document generator produce location-specific search documents, improving retrieval quality.`;\n\nconst responseFormat = z.object({\n lenses: z.array(z.object({\n label: z.string().describe('Specific description of the search perspective'),\n corpus: z.enum(['profiles', 'intents', 'premises']).describe('Search user profiles, user intents, or user premises (identity/values)'),\n reasoning: z.string().describe('Why this perspective is relevant'),\n })).min(1).max(5).describe('Inferred search lenses'),\n});\n\nconst logger = protocolLogger(\"LensInferrer\");\n\n/**\n * Infers search lenses from source text and optional profile context.\n * Each lens represents a search perspective tagged with a target corpus\n * (profiles or intents) for downstream HyDE document generation.\n */\nexport class LensInferrer {\n private model = createStructuredModel(\"lensInferrer\", responseFormat, {\n name: \"lens_inferrer\",\n });\n\n /**\n * Infer search lenses from source text and optional profile context.\n *\n * @param input - Source text, optional profile context, optional max lenses\n * @returns Array of inferred lenses with corpus tags; empty array on failure\n */\n @Timed()\n async infer(input: LensInferenceInput): Promise<LensInferenceOutput> {\n const { sourceText, profileContext, maxLenses = 3 } = input;\n\n logger.verbose('Inferring lenses', {\n sourceTextLength: sourceText.length,\n hasProfileContext: !!profileContext,\n maxLenses,\n });\n\n let humanPrompt = `Identify up to ${maxLenses} search perspectives for finding relevant matches.\\n\\nSource: \"${sourceText}\"`;\n\n if (profileContext) {\n humanPrompt += `\\n\\nUser context: ${profileContext}`;\n }\n\n const messages = [\n new SystemMessage(SYSTEM_PROMPT),\n new HumanMessage(humanPrompt),\n ];\n\n try {\n const result = await invokeWithAbortSignal(this.model, messages);\n const parsed = responseFormat.parse(result);\n const lenses = parsed.lenses.slice(0, maxLenses);\n\n logger.verbose('Lenses inferred', {\n count: lenses.length,\n lenses: lenses.map(l => ({ label: l.label, corpus: l.corpus })),\n });\n\n return { lenses };\n } catch (error: unknown) {\n logger.error('Lens inference failed', { error });\n return { lenses: [] };\n }\n }\n}\n"]}
1
+ {"version":3,"file":"lens.inferrer.js","sourceRoot":"/","sources":["shared/hyde/lens.inferrer.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Lens Inferrer Agent: analyzes source text (intent or query) with optional\n * profile context and infers 1-N search lenses, each tagged with a target corpus.\n * Replaces the hardcoded HydeStrategy enum and regex-based selectStrategiesFromQuery.\n */\nimport type { BaseLanguageModelInput } from '@langchain/core/language_models/base';\nimport { HumanMessage, SystemMessage } from '@langchain/core/messages';\nimport { z } from 'zod';\n\nimport { createStructuredModel } from \"../agent/model.config.js\";\nimport { invokeWithAbortSignal } from \"../agent/model-signal.js\";\nimport { protocolLogger } from '../observability/protocol.logger.js';\nimport { Timed } from \"../observability/performance.js\";\nimport { HydeSourceFrameSchema, sanitizeHydeSourceFrame, type HydeSourceFrame } from './hyde.frame.js';\n\nexport type HydeTargetCorpus = 'profiles' | 'intents' | 'premises';\n\n/** A single inferred lens — a search perspective the LLM decided is relevant. */\nexport interface Lens {\n /** Free-text description (e.g. \"crypto infrastructure VC\"). */\n label: string;\n /** Which vector index to search: user profiles or user intents. */\n corpus: HydeTargetCorpus;\n /** Why this perspective is relevant (for logging/trace). */\n reasoning: string;\n}\n\nexport interface LensInferenceInput {\n /** Intent payload or search query. */\n sourceText: string;\n /** User's profile summary for domain context (optional). */\n profileContext?: string;\n /** Maximum number of lenses to infer (default 3). */\n maxLenses?: number;\n /** Use the source-grounded frame-v1 inference path. */\n frameConstrained?: boolean;\n}\n\nexport interface LensInferenceOutput {\n lenses: Lens[];\n /** Sanitized source frame, present only for frame-constrained inference. */\n sourceFrame?: HydeSourceFrame;\n}\n\nconst SYSTEM_PROMPT = `You analyze goals and search queries to identify the most relevant perspectives for finding matching people in a professional network.\n\nFor each perspective you identify, specify:\n1. A clear, specific description of who or what to search for\n2. Whether to search \"profiles\" (user bios, expertise, backgrounds), \"intents\" (stated goals, needs, aspirations), or \"premises\" (identity assertions, values, worldview)\n3. A brief reason why this perspective is relevant\n\nGuidelines:\n- Be specific and domain-aware. \"early-stage crypto infrastructure investor\" is better than \"investor\".\n- Consider both sides: who can help the person AND whose goals complement theirs.\n- When user context is provided, tailor perspectives to their domain (e.g. a DePIN founder searching for \"investors\" needs crypto-native infra investors specifically).\n- Generate only perspectives that add distinct search value — don't repeat similar angles.\n- Use \"profiles\" when looking for a type of person (expert, advisor, leader). Use \"intents\" when looking for a complementary goal or need (someone raising, someone hiring, someone seeking collaboration). Use \"premises\" when looking for someone whose identity, values, or worldview aligns — stable traits rather than transient goals.\n- Always include at least one \"profiles\" perspective when the source describes a need that a specific type of professional could fulfill. Most intents benefit from profile-based discovery.\n- LOCATION AWARENESS: When the source text or user context mentions a specific location (city, region, country), incorporate it into lens descriptions. For example, \"investors in San Francisco\" should produce a lens like \"SF-based early-stage investor\" rather than just \"early-stage investor\". This helps the hypothetical document generator produce location-specific search documents, improving retrieval quality.`;\n\n/** Source-grounded system prompt used only by frame extraction. */\nexport const FRAME_SYSTEM_PROMPT = `You extract a source-grounded frame for semantic retrieval from sourceText alone.\n\nSource-frame rules:\n- Extract evidence ONLY from sourceText.\n- Every frame element must include an evidence field copied as an exact substring of sourceText.\n- sourceRoles describe roles held or offered by the source side.\n- sourceRoles and counterpartRoles MUST use generic lower-case role labels only (for example, \"founder\", \"investor\", or \"technical advisor\"). Never put a person, organization, product, location, time, number, credential, or exclusivity detail in a role label.\n- counterpartRoles describe reciprocal or complementary target roles. A generic role may be inferred, but its evidence must be an exact sourceText span that supports the inference.\n- hardConstraints contain only explicit constraints and classify each as location, time, numeric, credential, organization, exclusivity, or other.\n- namedEntities contain only proper names explicitly present in sourceText and classify each as person, organization, product, location, event, or other.\n- domainVocabulary contains source domain terms worth preserving.`;\n\nconst lensSchema = z.object({\n label: z.string().describe('Specific description of the search perspective'),\n corpus: z.enum(['profiles', 'intents', 'premises']).describe('Search user profiles, user intents, or user premises (identity/values)'),\n reasoning: z.string().describe('Why this perspective is relevant'),\n});\n\nconst responseFormat = z.object({\n lenses: z.array(lensSchema).min(1).max(5).describe('Inferred search lenses'),\n});\n\n/** Structured-output schema used only by source-frame extraction. */\nexport const FrameResponseSchema = z.object({\n sourceFrame: HydeSourceFrameSchema,\n});\n\ntype ModelInput = BaseLanguageModelInput;\n\n/** Minimal structured model contract used for deterministic injection in tests. */\nexport interface LensStructuredModel {\n invoke(input: ModelInput, config?: { signal?: AbortSignal }): Promise<unknown>;\n}\n\nexport interface LensInferrerOptions {\n legacyModel?: LensStructuredModel;\n frameModel?: LensStructuredModel;\n}\n\nconst logger = protocolLogger(\"LensInferrer\");\n\n/** Infers search lenses from source text and optional profile context. */\nexport class LensInferrer {\n private legacyModel?: LensStructuredModel;\n private frameModel?: LensStructuredModel;\n\n constructor(options: LensInferrerOptions = {}) {\n // Preserve legacy construction behavior in production. Frame-only model\n // injection deliberately avoids constructing a provider-backed legacy model.\n this.legacyModel = options.legacyModel\n ?? (options.frameModel ? undefined : createStructuredModel(\"lensInferrer\", responseFormat, { name: \"lens_inferrer\" }));\n this.frameModel = options.frameModel;\n }\n\n private getLegacyModel(): LensStructuredModel {\n this.legacyModel ??= createStructuredModel(\"lensInferrer\", responseFormat, {\n name: \"lens_inferrer\",\n });\n return this.legacyModel;\n }\n\n private getFrameModel(): LensStructuredModel {\n this.frameModel ??= createStructuredModel(\"lensInferrer\", FrameResponseSchema, {\n name: \"lens_inferrer_frame_v1\",\n });\n return this.frameModel;\n }\n\n /** Infer search lenses while preserving the legacy path unless explicitly enabled. */\n @Timed()\n async infer(input: LensInferenceInput): Promise<LensInferenceOutput> {\n const { sourceText, profileContext, maxLenses = 3, frameConstrained = false } = input;\n\n logger.verbose('Inferring lenses', {\n sourceTextLength: sourceText.length,\n hasProfileContext: !!profileContext,\n maxLenses,\n frameConstrained,\n });\n\n let humanPrompt = `Identify up to ${maxLenses} search perspectives for finding relevant matches.\\n\\nSource: \"${sourceText}\"`;\n\n if (profileContext) {\n humanPrompt += `\\n\\nUser context: ${profileContext}`;\n }\n\n const messages = [\n new SystemMessage(SYSTEM_PROMPT),\n new HumanMessage(humanPrompt),\n ];\n\n if (!frameConstrained) {\n try {\n const result = await invokeWithAbortSignal(this.getLegacyModel(), messages);\n const parsed = responseFormat.parse(result);\n const lenses = parsed.lenses.slice(0, maxLenses);\n\n logger.verbose('Lenses inferred', {\n count: lenses.length,\n lenses: lenses.map(l => ({ label: l.label, corpus: l.corpus })),\n });\n\n return { lenses };\n } catch (error: unknown) {\n logger.error('Lens inference failed', { error });\n return { lenses: [] };\n }\n }\n\n const frameMessages = [\n new SystemMessage(FRAME_SYSTEM_PROMPT),\n new HumanMessage(`Extract the source frame.\\n\\nSource: \"${sourceText}\"`),\n ];\n const lensPromise = (async () => {\n const result = await invokeWithAbortSignal(this.getLegacyModel(), messages);\n return responseFormat.parse(result).lenses.slice(0, maxLenses);\n })();\n const framePromise = (async () => {\n const result = await invokeWithAbortSignal(this.getFrameModel(), frameMessages);\n const parsed = FrameResponseSchema.parse(result);\n return sanitizeHydeSourceFrame(sourceText, parsed.sourceFrame);\n })();\n const [lensResult, frameResult] = await Promise.allSettled([lensPromise, framePromise]);\n\n if (lensResult.status === 'rejected') {\n logger.error('Lens inference failed', { error: lensResult.reason });\n return { lenses: [] };\n }\n\n const lenses = lensResult.value;\n logger.verbose('Frame-constrained lenses inferred', { count: lenses.length });\n\n if (frameResult.status === 'rejected') {\n logger.error('Source frame extraction failed', { error: frameResult.reason });\n return {\n lenses,\n sourceFrame: {\n sourceRoles: [],\n counterpartRoles: [],\n hardConstraints: [],\n namedEntities: [],\n domainVocabulary: [],\n },\n };\n }\n\n return { lenses, sourceFrame: frameResult.value };\n }\n}\n"]}
@@ -88,6 +88,10 @@ export interface OpportunitySignal {
88
88
  detail?: string;
89
89
  /** Optional source question for reversible pool-preference provenance. */
90
90
  questionId?: string;
91
+ /** Recipient provenance for pool-discriminator signals. */
92
+ recipientUserId?: string;
93
+ /** Intent-pool provenance for pool-discriminator signals. */
94
+ intentId?: string;
91
95
  }
92
96
  /** LLM-generated interpretation of an opportunity's category and confidence. */
93
97
  export interface OpportunityInterpretation {
@@ -264,6 +268,10 @@ export interface SimilarIntentSearchOptions {
264
268
  * Represents a user's membership in an index with full details.
265
269
  * Used for displaying network memberships in chat (index_query).
266
270
  */
271
+ export interface ActiveNetworkMembershipPair {
272
+ userId: string;
273
+ networkId: string;
274
+ }
267
275
  export interface NetworkMembership {
268
276
  /** Unique identifier of the index */
269
277
  networkId: string;
@@ -457,6 +465,14 @@ export interface Opportunity {
457
465
  expiresAt: Date | null;
458
466
  metadata?: Record<string, unknown> | null;
459
467
  }
468
+ export interface OpportunityNetworkEligibility {
469
+ /** User whose active memberships define the discovery boundary. */
470
+ ownerUserId: string;
471
+ /** Request/intent-authorized networks after the latest graph-side recomputation. */
472
+ allowedNetworkIds: string[];
473
+ /** When present, each actor network must remain assigned to this intent through commit. */
474
+ triggerIntentId?: string;
475
+ }
460
476
  export interface CreateOpportunityData {
461
477
  detection: OpportunityDetection;
462
478
  actors: OpportunityActor[];
@@ -706,6 +722,12 @@ export interface Database {
706
722
  * @returns The membership or null if not found
707
723
  */
708
724
  getNetworkMembership(networkId: string, userId: string): Promise<NetworkMembership | null>;
725
+ /**
726
+ * Return only requested user/network pairs backed by a live membership row
727
+ * and a non-deleted network. Permissions are intentionally not filtered:
728
+ * personal-network contacts are valid discovery participants.
729
+ */
730
+ getActiveNetworkMembershipPairs(pairs: ActiveNetworkMembershipPair[]): Promise<ActiveNetworkMembershipPair[]>;
709
731
  /**
710
732
  * Get index by ID with core fields. Used for opportunity presentation and context rendering.
711
733
  */
@@ -1082,6 +1104,17 @@ export interface Database {
1082
1104
  * @returns The created opportunity
1083
1105
  */
1084
1106
  createOpportunity(data: CreateOpportunityData): Promise<Opportunity>;
1107
+ /**
1108
+ * Atomically create only while every actor still has an active membership on
1109
+ * the actor's network. Implementations lock the membership rows through the
1110
+ * insert commit so concurrent removal cannot race opportunity creation.
1111
+ */
1112
+ createOpportunityIfNetworkEligible?(data: CreateOpportunityData, eligibility: OpportunityNetworkEligibility): Promise<Opportunity | null>;
1113
+ /**
1114
+ * Atomically update status only while the supplied participant anchors remain
1115
+ * active. Used for discovery dedup reactivation races.
1116
+ */
1117
+ updateOpportunityStatusIfNetworkEligible?(id: string, status: OpportunityStatus, actors: OpportunityActor[], eligibility: OpportunityNetworkEligibility): Promise<Opportunity | null>;
1085
1118
  /**
1086
1119
  * Get a single opportunity by ID.
1087
1120
  *
@@ -1127,6 +1160,12 @@ export interface Database {
1127
1160
  * @returns Array of opportunities
1128
1161
  */
1129
1162
  getOpportunitiesForUser(userId: string, options?: OpportunityQueryOptions): Promise<Opportunity[]>;
1163
+ /**
1164
+ * Get the live candidate pool created exactly by one intent and visible to
1165
+ * its recipient. Unlike selected-intent reads, this never falls back to an
1166
+ * actor.intent match.
1167
+ */
1168
+ getLivePoolOpportunitiesForIntent(recipientUserId: string, intentId: string): Promise<Opportunity[]>;
1130
1169
  /**
1131
1170
  * Get opportunities in an index (for index admins).
1132
1171
  *
@@ -1178,6 +1217,11 @@ export interface Database {
1178
1217
  created: Opportunity;
1179
1218
  expired: Opportunity[];
1180
1219
  }>;
1220
+ /** Eligibility-locked variant of create+expire for discovery persistence. */
1221
+ createOpportunityAndExpireIdsIfNetworkEligible?(data: CreateOpportunityData, expireIds: string[], eligibility: OpportunityNetworkEligibility): Promise<{
1222
+ created: Opportunity;
1223
+ expired: Opportunity[];
1224
+ } | null>;
1181
1225
  /**
1182
1226
  * Check if an opportunity already exists between the given actors in the index (deduplication).
1183
1227
  *
@@ -1737,7 +1781,7 @@ export type PremiseGraphDatabase = Pick<Database, 'createPremise' | 'getPremise'
1737
1781
  *
1738
1782
  * Access layer: Both UserDatabase + SystemDatabase (orchestrates all operations)
1739
1783
  */
1740
- export type ChatGraphCompositeDatabase = Pick<Database, 'getProfile' | 'getActiveIntents' | 'getActiveIntentsAcrossIndexes' | 'getIntentsInIndexForMember' | 'getUser' | 'updateUser' | 'getUserSocials' | 'setUserSocials' | 'saveProfile' | 'softDeleteGhost' | 'createIntent' | 'updateIntent' | 'archiveIntent' | 'createOpportunity' | 'getOpportunity' | 'getOpportunitiesByIds' | 'opportunityExistsBetweenActors' | 'findOpportunitiesByActors' | 'getOpportunitiesForUser' | 'updateOpportunityStatus' | 'updateOpportunityActorApproval' | 'stampOpportunityActorAction' | 'getOrCreateDM' | 'getHydeDocument' | 'getHydeDocumentsForSource' | 'saveHydeDocument' | 'getIntent' | 'getPublicIndexesNotJoined' | 'getUserIndexIds' | 'getAssignmentNetworkMembershipsForUser' | 'getAssignmentNetworkIdsForUser' | 'getNetworkMemberships' | 'getNetworkMembership' | 'getNetwork' | 'getNetworkWithPermissions' | 'getIntentForIndexing' | 'getNetworkMemberContext' | 'getNetworkAssignmentContext' | 'isIntentAssignedToIndex' | 'assignIntentToNetwork' | 'unassignIntentFromIndex' | 'getNetworkIdsForIntent' | 'getIntentIndexScores' | 'getPersonalIndexesForContact' | 'getOwnedIndexes' | 'isIndexOwner' | 'isNetworkMember' | 'getNetworkMembersForOwner' | 'getNetworkMembersForMember' | 'getMembersFromUserIndexes' | 'getNetworkIntentsForOwner' | 'getNetworkIntentsForMember' | 'updateIndexSettings' | 'softDeleteNetwork' | 'deleteProfile' | 'getProfileByUserId' | 'createNetwork' | 'getNetworkMemberCount' | 'addMemberToNetwork' | 'removeMemberFromIndex' | 'findDuplicateUser' | 'mergeGhostUser' | 'getPremisesForUser' | 'getPremisesForUserInNetworks' | 'createPremise' | 'getPremise' | 'updatePremise' | 'assignPremiseToNetwork' | 'getPremiseNetworks' | 'searchPremisesBySimilarity' | 'searchPremisesBySimilarityBatch' | 'getUserContext' | 'getUserContexts' | 'searchIntentsByContextEmbedding'> & Pick<NegotiationQueries, 'getNegotiationTaskForOpportunity'>;
1784
+ export type ChatGraphCompositeDatabase = Pick<Database, 'getProfile' | 'getActiveIntents' | 'getActiveIntentsAcrossIndexes' | 'getIntentsInIndexForMember' | 'getUser' | 'updateUser' | 'getUserSocials' | 'setUserSocials' | 'saveProfile' | 'softDeleteGhost' | 'createIntent' | 'updateIntent' | 'archiveIntent' | 'createOpportunity' | 'createOpportunityIfNetworkEligible' | 'createOpportunityAndExpireIdsIfNetworkEligible' | 'updateOpportunityStatusIfNetworkEligible' | 'getOpportunity' | 'getOpportunitiesByIds' | 'opportunityExistsBetweenActors' | 'findOpportunitiesByActors' | 'getOpportunitiesForUser' | 'updateOpportunityStatus' | 'updateOpportunityActorApproval' | 'stampOpportunityActorAction' | 'getOrCreateDM' | 'getHydeDocument' | 'getHydeDocumentsForSource' | 'saveHydeDocument' | 'getIntent' | 'getPublicIndexesNotJoined' | 'getUserIndexIds' | 'getAssignmentNetworkMembershipsForUser' | 'getAssignmentNetworkIdsForUser' | 'getNetworkMemberships' | 'getNetworkMembership' | 'getActiveNetworkMembershipPairs' | 'getNetwork' | 'getNetworkWithPermissions' | 'getIntentForIndexing' | 'getNetworkMemberContext' | 'getNetworkAssignmentContext' | 'isIntentAssignedToIndex' | 'assignIntentToNetwork' | 'unassignIntentFromIndex' | 'getNetworkIdsForIntent' | 'getIntentIndexScores' | 'getPersonalIndexesForContact' | 'getOwnedIndexes' | 'isIndexOwner' | 'isNetworkMember' | 'getNetworkMembersForOwner' | 'getNetworkMembersForMember' | 'getMembersFromUserIndexes' | 'getNetworkIntentsForOwner' | 'getNetworkIntentsForMember' | 'updateIndexSettings' | 'softDeleteNetwork' | 'deleteProfile' | 'getProfileByUserId' | 'createNetwork' | 'getNetworkMemberCount' | 'addMemberToNetwork' | 'removeMemberFromIndex' | 'findDuplicateUser' | 'mergeGhostUser' | 'getPremisesForUser' | 'getPremisesForUserInNetworks' | 'createPremise' | 'getPremise' | 'updatePremise' | 'assignPremiseToNetwork' | 'getPremiseNetworks' | 'searchPremisesBySimilarity' | 'searchPremisesBySimilarityBatch' | 'getUserContext' | 'getUserContexts' | 'searchIntentsByContextEmbedding'> & Pick<NegotiationQueries, 'getNegotiationTaskForOpportunity'>;
1741
1785
  /**
1742
1786
  * Database interface for Opportunity Graph operations.
1743
1787
  * Includes prep/scope (network membership, intents, index details), persist (create, dedupe),
@@ -1745,7 +1789,7 @@ export type ChatGraphCompositeDatabase = Pick<Database, 'getProfile' | 'getActiv
1745
1789
  *
1746
1790
  * Access layer: SystemDatabase (cross-user opportunity operations)
1747
1791
  */
1748
- export type OpportunityGraphDatabase = Pick<Database, 'getProfile' | 'createOpportunity' | 'opportunityExistsBetweenActors' | 'findOpportunitiesByActors' | 'getUserIndexIds' | 'getNetworkMemberships' | 'getActiveIntents' | 'getNetworkIdsForIntent' | 'getNetwork' | 'getNetworkMemberCount' | 'getIntentIndexScores' | 'getNetworkMemberContext' | 'getNetworkAssignmentContext' | 'getOpportunity' | 'getOpportunitiesForUser' | 'updateOpportunityStatus' | 'stampOpportunityActorAction' | 'updateOpportunityActorApproval' | 'isNetworkMember' | 'isIndexOwner' | 'getUser' | 'getOrCreateDM' | 'getIntent' | 'getPremisesForUser' | 'getPremisesForUserInNetworks' | 'searchPremisesBySimilarity' | 'searchPremisesBySimilarityBatch' | 'getUserContext' | 'getUserContexts' | 'searchIntentsByContextEmbedding' | 'getHydeDocumentsForSource'> & Pick<NegotiationQueries, 'getNegotiationTaskForOpportunity'>;
1792
+ export type OpportunityGraphDatabase = Pick<Database, 'getProfile' | 'createOpportunity' | 'createOpportunityIfNetworkEligible' | 'createOpportunityAndExpireIdsIfNetworkEligible' | 'updateOpportunityStatusIfNetworkEligible' | 'opportunityExistsBetweenActors' | 'findOpportunitiesByActors' | 'getUserIndexIds' | 'getNetworkMemberships' | 'getActiveNetworkMembershipPairs' | 'getActiveIntents' | 'getNetworkIdsForIntent' | 'getNetwork' | 'getNetworkMemberCount' | 'getIntentIndexScores' | 'getNetworkMemberContext' | 'getNetworkAssignmentContext' | 'getOpportunity' | 'getOpportunitiesForUser' | 'updateOpportunityStatus' | 'stampOpportunityActorAction' | 'updateOpportunityActorApproval' | 'isNetworkMember' | 'isIndexOwner' | 'getUser' | 'getOrCreateDM' | 'getIntent' | 'getPremisesForUser' | 'getPremisesForUserInNetworks' | 'searchPremisesBySimilarity' | 'searchPremisesBySimilarityBatch' | 'getUserContext' | 'getUserContexts' | 'searchIntentsByContextEmbedding' | 'getHydeDocumentsForSource'> & Pick<NegotiationQueries, 'getNegotiationTaskForOpportunity'>;
1749
1793
  /**
1750
1794
  * Negotiation-specific query operations not covered by generic
1751
1795
  * conversation/task primitives.