@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.
- package/CHANGELOG.md +6 -0
- package/dist/contact/contact.inviter.d.ts.map +1 -1
- package/dist/contact/contact.inviter.js +12 -5
- package/dist/contact/contact.inviter.js.map +1 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/opportunity/delivery-card.cache.d.ts.map +1 -1
- package/dist/opportunity/delivery-card.cache.js +7 -3
- package/dist/opportunity/delivery-card.cache.js.map +1 -1
- package/dist/opportunity/discriminator/discriminator.adjustments.d.ts +22 -15
- package/dist/opportunity/discriminator/discriminator.adjustments.d.ts.map +1 -1
- package/dist/opportunity/discriminator/discriminator.adjustments.js +39 -20
- package/dist/opportunity/discriminator/discriminator.adjustments.js.map +1 -1
- package/dist/opportunity/feed/feed.categorizer.d.ts.map +1 -1
- package/dist/opportunity/feed/feed.categorizer.js +6 -0
- package/dist/opportunity/feed/feed.categorizer.js.map +1 -1
- package/dist/opportunity/feed/feed.graph.d.ts +2 -0
- package/dist/opportunity/feed/feed.graph.d.ts.map +1 -1
- package/dist/opportunity/feed/feed.graph.js +53 -28
- package/dist/opportunity/feed/feed.graph.js.map +1 -1
- package/dist/opportunity/feed/feed.state.d.ts +3 -1
- package/dist/opportunity/feed/feed.state.d.ts.map +1 -1
- package/dist/opportunity/feed/feed.state.js.map +1 -1
- package/dist/opportunity/opportunity.claim-safety.d.ts +25 -0
- package/dist/opportunity/opportunity.claim-safety.d.ts.map +1 -0
- package/dist/opportunity/opportunity.claim-safety.js +89 -0
- package/dist/opportunity/opportunity.claim-safety.js.map +1 -0
- package/dist/opportunity/opportunity.discover.d.ts.map +1 -1
- package/dist/opportunity/opportunity.discover.js +6 -1
- package/dist/opportunity/opportunity.discover.js.map +1 -1
- package/dist/opportunity/opportunity.evaluator.d.ts.map +1 -1
- package/dist/opportunity/opportunity.evaluator.js +13 -8
- package/dist/opportunity/opportunity.evaluator.js.map +1 -1
- package/dist/opportunity/opportunity.graph.d.ts +36 -0
- package/dist/opportunity/opportunity.graph.d.ts.map +1 -1
- package/dist/opportunity/opportunity.graph.js +177 -18
- package/dist/opportunity/opportunity.graph.js.map +1 -1
- package/dist/opportunity/opportunity.persist.d.ts +8 -1
- package/dist/opportunity/opportunity.persist.d.ts.map +1 -1
- package/dist/opportunity/opportunity.persist.js +23 -2
- package/dist/opportunity/opportunity.persist.js.map +1 -1
- package/dist/opportunity/opportunity.presentation-cache.d.ts +7 -0
- package/dist/opportunity/opportunity.presentation-cache.d.ts.map +1 -0
- package/dist/opportunity/opportunity.presentation-cache.js +15 -0
- package/dist/opportunity/opportunity.presentation-cache.js.map +1 -0
- package/dist/opportunity/opportunity.presentation.d.ts.map +1 -1
- package/dist/opportunity/opportunity.presentation.js +8 -5
- package/dist/opportunity/opportunity.presentation.js.map +1 -1
- package/dist/opportunity/opportunity.presenter.d.ts +4 -4
- package/dist/opportunity/opportunity.presenter.d.ts.map +1 -1
- package/dist/opportunity/opportunity.presenter.js +55 -14
- package/dist/opportunity/opportunity.presenter.js.map +1 -1
- package/dist/opportunity/opportunity.safe-presentation.d.ts +1 -1
- package/dist/opportunity/opportunity.safe-presentation.d.ts.map +1 -1
- package/dist/opportunity/opportunity.safe-presentation.js +22 -9
- package/dist/opportunity/opportunity.safe-presentation.js.map +1 -1
- package/dist/opportunity/opportunity.state.d.ts +3 -0
- package/dist/opportunity/opportunity.state.d.ts.map +1 -1
- package/dist/opportunity/opportunity.state.js.map +1 -1
- package/dist/opportunity/opportunity.tools.d.ts +1 -17
- package/dist/opportunity/opportunity.tools.d.ts.map +1 -1
- package/dist/opportunity/opportunity.tools.js +32 -2
- package/dist/opportunity/opportunity.tools.js.map +1 -1
- package/dist/shared/agent/model.config.d.ts +5 -0
- package/dist/shared/agent/model.config.d.ts.map +1 -1
- package/dist/shared/agent/model.config.js +1 -0
- package/dist/shared/agent/model.config.js.map +1 -1
- package/dist/shared/hyde/hyde.documents.d.ts +10 -0
- package/dist/shared/hyde/hyde.documents.d.ts.map +1 -0
- package/dist/shared/hyde/hyde.documents.js +50 -0
- package/dist/shared/hyde/hyde.documents.js.map +1 -0
- package/dist/shared/hyde/hyde.env.d.ts +9 -0
- package/dist/shared/hyde/hyde.env.d.ts.map +1 -0
- package/dist/shared/hyde/hyde.env.js +10 -0
- package/dist/shared/hyde/hyde.env.js.map +1 -0
- package/dist/shared/hyde/hyde.frame.d.ts +151 -0
- package/dist/shared/hyde/hyde.frame.d.ts.map +1 -0
- package/dist/shared/hyde/hyde.frame.js +108 -0
- package/dist/shared/hyde/hyde.frame.js.map +1 -0
- package/dist/shared/hyde/hyde.generator.d.ts +23 -11
- package/dist/shared/hyde/hyde.generator.d.ts.map +1 -1
- package/dist/shared/hyde/hyde.generator.js +50 -21
- package/dist/shared/hyde/hyde.generator.js.map +1 -1
- package/dist/shared/hyde/hyde.graph.d.ts +58 -17
- package/dist/shared/hyde/hyde.graph.d.ts.map +1 -1
- package/dist/shared/hyde/hyde.graph.js +333 -89
- package/dist/shared/hyde/hyde.graph.js.map +1 -1
- package/dist/shared/hyde/hyde.state.d.ts +19 -2
- package/dist/shared/hyde/hyde.state.d.ts.map +1 -1
- package/dist/shared/hyde/hyde.state.js +23 -3
- package/dist/shared/hyde/hyde.state.js.map +1 -1
- package/dist/shared/hyde/hyde.validator.d.ts +79 -0
- package/dist/shared/hyde/hyde.validator.d.ts.map +1 -0
- package/dist/shared/hyde/hyde.validator.js +49 -0
- package/dist/shared/hyde/hyde.validator.js.map +1 -0
- package/dist/shared/hyde/lens.inferrer.d.ts +190 -12
- package/dist/shared/hyde/lens.inferrer.d.ts.map +1 -1
- package/dist/shared/hyde/lens.inferrer.js +93 -38
- package/dist/shared/hyde/lens.inferrer.js.map +1 -1
- package/dist/shared/interfaces/database.interface.d.ts +46 -2
- package/dist/shared/interfaces/database.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/database.interface.js.map +1 -1
- 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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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":"
|
|
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(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
87
|
-
|
|
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.
|