@indexnetwork/protocol 8.1.0-rc.421.1 → 8.2.0-rc.423.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.
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Centralized accessors for discovery match-type environment variables.
3
+ *
4
+ * DISCOVERY_ALLOWED_TYPES CSV of `intent`, `profile` (default: both).
5
+ * Master gate for which data types may participate
6
+ * in opportunity matching. `profile` is an umbrella
7
+ * whose representation is selected by
8
+ * DISCOVERY_PROFILE_SOURCE. Unknown tokens warn once
9
+ * and are ignored; if no valid tokens remain, falls
10
+ * back to both-allowed with a warning (a typo must
11
+ * never disable all discovery).
12
+ * DISCOVERY_PROFILE_SOURCE `premise` (default, heavyweight: atomic premises
13
+ * as profile corpus + premise-to-premise) or
14
+ * `user_context` (lightweight: synthesized context
15
+ * paragraphs as profile corpus + context-to-context).
16
+ * Unknown values warn once and fall back to `premise`.
17
+ *
18
+ * All reads go through this module — do not read these variables via
19
+ * `process.env` elsewhere. Values are read on every call (no caching) so
20
+ * tests and long-lived processes observe changes.
21
+ */
22
+ import { protocolLogger } from '../shared/observability/protocol.logger.js';
23
+ const envLog = protocolLogger('Discovery:env');
24
+ const VALID_TOKENS = new Set(['intent', 'profile']);
25
+ const BOTH = new Set(['intent', 'profile']);
26
+ /** Tokens/values already warned about (warn-once per process). */
27
+ const warned = new Set();
28
+ /** Test hook: clear warn-once state so each test observes warnings. */
29
+ export function resetDiscoveryEnvWarningsForTests() {
30
+ warned.clear();
31
+ }
32
+ function warnOnce(key, message) {
33
+ if (warned.has(key))
34
+ return;
35
+ warned.add(key);
36
+ envLog.warn(message);
37
+ }
38
+ /** Current DISCOVERY_ALLOWED_TYPES set (default: intent + profile). */
39
+ export function discoveryAllowedTypes() {
40
+ const raw = process.env.DISCOVERY_ALLOWED_TYPES;
41
+ if (raw === undefined || raw.trim() === '')
42
+ return BOTH;
43
+ const parsed = new Set();
44
+ for (const token of raw.split(',')) {
45
+ const t = token.trim().toLowerCase();
46
+ if (!t)
47
+ continue;
48
+ if (VALID_TOKENS.has(t)) {
49
+ parsed.add(t);
50
+ }
51
+ else {
52
+ warnOnce(`token:${t}`, `DISCOVERY_ALLOWED_TYPES: ignoring unknown token "${t}" (valid: intent, profile)`);
53
+ }
54
+ }
55
+ if (parsed.size === 0) {
56
+ warnOnce('fallback', `DISCOVERY_ALLOWED_TYPES="${raw}" has no valid tokens; falling back to intent,profile`);
57
+ return BOTH;
58
+ }
59
+ return parsed;
60
+ }
61
+ /** True when intents may participate in matching (source or candidate). */
62
+ export function discoveryIntentMatchingEnabled() {
63
+ return discoveryAllowedTypes().has('intent');
64
+ }
65
+ /** True when profile data (premises or user_contexts) may participate. */
66
+ export function discoveryProfileMatchingEnabled() {
67
+ return discoveryAllowedTypes().has('profile');
68
+ }
69
+ /** Current DISCOVERY_PROFILE_SOURCE (default: premise). */
70
+ export function discoveryProfileSource() {
71
+ const raw = process.env.DISCOVERY_PROFILE_SOURCE;
72
+ if (raw === undefined || raw.trim() === '')
73
+ return 'premise';
74
+ const v = raw.trim().toLowerCase();
75
+ if (v === 'premise' || v === 'user_context')
76
+ return v;
77
+ warnOnce(`source:${v}`, `DISCOVERY_PROFILE_SOURCE: unknown value "${raw}"; falling back to "premise" (valid: premise, user_context)`);
78
+ return 'premise';
79
+ }
@@ -3,12 +3,13 @@ export interface EvidenceCandidateInput {
3
3
  networkId: string;
4
4
  similarity: number;
5
5
  lens: string;
6
- discoverySource?: 'query' | 'premise-similarity' | 'context-to-intent';
6
+ discoverySource?: 'query' | 'premise-similarity' | 'context-to-intent' | 'context-similarity';
7
7
  matchedStrategies?: string[];
8
8
  sourcePremiseId?: string;
9
9
  candidatePremiseId?: string;
10
10
  candidateIntentId?: string;
11
11
  sourceContextId?: string;
12
+ candidateContextId?: string;
12
13
  candidatePayload?: string;
13
14
  candidateSummary?: string;
14
15
  }
@@ -11,6 +11,7 @@ export function buildCandidateEvidence(candidate) {
11
11
  candidatePremiseId: candidate.candidatePremiseId,
12
12
  candidateIntentId: candidate.candidateIntentId,
13
13
  sourceContextId: candidate.sourceContextId,
14
+ candidateContextId: candidate.candidateContextId,
14
15
  payload: candidate.candidatePayload,
15
16
  summary: candidate.candidateSummary,
16
17
  assertionText: candidate.candidatePremiseId ? candidate.candidatePayload : undefined,
@@ -29,6 +30,7 @@ export function mergeOpportunityEvidence(...groups) {
29
30
  evidence.candidatePremiseId ?? '',
30
31
  evidence.candidateIntentId ?? '',
31
32
  evidence.sourceContextId ?? '',
33
+ evidence.candidateContextId ?? '',
32
34
  evidence.lens ?? '',
33
35
  ].join('|');
34
36
  const existing = byKey.get(key);
@@ -52,6 +54,7 @@ export function renderOpportunityEvidenceForPrompt(evidence) {
52
54
  item.candidatePremiseId ? `candidatePremise=${item.candidatePremiseId}` : undefined,
53
55
  item.candidateIntentId ? `candidateIntent=${item.candidateIntentId}` : undefined,
54
56
  item.sourceContextId ? `sourceContext=${item.sourceContextId}` : undefined,
57
+ item.candidateContextId ? `candidateContext=${item.candidateContextId}` : undefined,
55
58
  item.matchedStrategies?.length ? `strategies=${item.matchedStrategies.join(',')}` : undefined,
56
59
  ].filter(Boolean).join(', ');
57
60
  const text = item.summary ?? item.payload ?? item.assertionText ?? '';
@@ -59,19 +62,25 @@ export function renderOpportunityEvidenceForPrompt(evidence) {
59
62
  // so it does not treat a high RAG score as domain confirmation.
60
63
  // (text should be populated by Fix A; this fallback fires if the DB fetch
61
64
  // failed or the adapter omitted getPremise).
62
- const domainCaution = item.kind === 'query_premise' && !text
65
+ const domainCaution = (item.kind === 'query_premise' && !text)
63
66
  ? ' [premise text unavailable — do NOT infer domain match from RAG score alone; verify domain alignment from profile]'
64
- : '';
67
+ : (item.kind === 'query_context' && !text)
68
+ ? ' [context text unavailable — do NOT infer domain match from RAG score alone; verify domain alignment from profile]'
69
+ : '';
65
70
  return ` - ${item.kind} on ${item.networkId} via ${item.lens ?? 'unknown'} score=${item.score?.toFixed(3) ?? '—'}${refs ? ` (${refs})` : ''}${text ? `: ${text}` : ''}${domainCaution}`;
66
71
  }).join('\n');
67
72
  }
68
73
  function resolveEvidenceKind(candidate) {
69
74
  if (candidate.discoverySource === 'premise-similarity')
70
75
  return 'premise_similarity';
76
+ if (candidate.discoverySource === 'context-similarity')
77
+ return 'context_similarity';
71
78
  if (candidate.discoverySource === 'context-to-intent')
72
79
  return 'context_to_intent';
73
80
  if (candidate.candidatePremiseId)
74
81
  return 'query_premise';
82
+ if (candidate.candidateContextId)
83
+ return 'query_context';
75
84
  if (candidate.candidateIntentId)
76
85
  return 'query_intent';
77
86
  return 'profile';
@@ -51,14 +51,16 @@ export interface CandidateMatch {
51
51
  candidatePremiseId?: Id<'premises'>;
52
52
  /** Source context that produced this candidate (set when discoverySource is 'context-to-intent'). */
53
53
  sourceContextId?: string;
54
+ /** Candidate context that matched this candidate (set for user_context-based matches). */
55
+ candidateContextId?: string;
54
56
  networkId: Id<'networks'>;
55
57
  similarity: number;
56
58
  /** Free-text lens label that produced this match. */
57
59
  lens: string;
58
60
  candidatePayload: string;
59
61
  candidateSummary?: string;
60
- /** How this candidate was found: 'query' (HyDE from search text), 'premise-similarity', or 'context-to-intent'. */
61
- discoverySource?: 'query' | 'premise-similarity' | 'context-to-intent';
62
+ /** How this candidate was found: 'query' (HyDE from search text), 'premise-similarity', 'context-to-intent', or 'context-similarity'. */
63
+ discoverySource?: 'query' | 'premise-similarity' | 'context-to-intent' | 'context-similarity';
62
64
  /** Which discovery strategies found this candidate (set by mergeStrategyCandidates). */
63
65
  matchedStrategies?: string[];
64
66
  /** Typed evidence that explains why this candidate entered evaluation. */
@@ -24,6 +24,8 @@ export { buildDiscoverySummary, toDiscoveryNegotiation, } from "../domain/negoti
24
24
  export type { NegotiationResolution } from "../domain/negotiation-summary.builder.js";
25
25
  export type { PoolCandidate, DiscriminatorMiningInput, MinedDiscriminator, ScoredDiscriminator, DiscriminatorShadowResult, } from "../discriminator/discriminator.types.js";
26
26
  export { poolQuestionsMiningMode, poolQuestionsMode, poolQuestionsPushMode, poolQuestionsStampNewborn, POOL_DISCRIMINATOR_MIN_POOL_SIZE, POOL_DISCRIMINATOR_MAX_CANDIDATES, POOL_DISCRIMINATOR_MAX_PUBLIC_CONTEXT_CHARS, POOL_QUESTION_MIN_VOI, POOL_QUESTION_MAX_PENDING_PER_INTENT, poolQuestionsRanking, POOL_RERUN_DEBOUNCE_MS, poolQuestionsVisitTrigger, POOL_VISIT_MINING_DEBOUNCE_MS, } from "../discriminator/discriminator.env.js";
27
+ export { discoveryAllowedTypes, discoveryIntentMatchingEnabled, discoveryProfileMatchingEnabled, discoveryProfileSource, resetDiscoveryEnvWarningsForTests, } from "../discovery.env.js";
28
+ export type { DiscoveryMatchType, DiscoveryProfileSource, } from "../discovery.env.js";
27
29
  export { buildPoolAdjustment, planPoolAdjustments, mergePoolAdjustment, } from "../discriminator/discriminator.adjustments.js";
28
30
  export type { PoolAdjustment, PoolAdjustmentSignal, } from "../discriminator/discriminator.adjustments.js";
29
31
  export { synthesizePoolQuestion, selectQuestionDiscriminators, toQuestionDiscriminator, BOTH_MATTER_LABEL, } from "../discriminator/discriminator.question.js";
@@ -21,6 +21,8 @@ export { safeFallbackSummary, SAFE_FALLBACK_MAX_CHARS, DEFAULT_EMPTY_FALLBACK_TE
21
21
  export { OPPORTUNITY_PRESENTATION_CACHE_VERSION, buildHomeCardPresentationCacheKey, buildHomeCategoryPresentationCacheKey, buildDeliveryCardPresentationCacheKey, buildApiChatCardPresentationCacheKey, } from "../domain/opportunity.presentation-cache.js";
22
22
  export { buildDiscoverySummary, toDiscoveryNegotiation, } from "../domain/negotiation-summary.builder.js";
23
23
  export { poolQuestionsMiningMode, poolQuestionsMode, poolQuestionsPushMode, poolQuestionsStampNewborn, POOL_DISCRIMINATOR_MIN_POOL_SIZE, POOL_DISCRIMINATOR_MAX_CANDIDATES, POOL_DISCRIMINATOR_MAX_PUBLIC_CONTEXT_CHARS, POOL_QUESTION_MIN_VOI, POOL_QUESTION_MAX_PENDING_PER_INTENT, poolQuestionsRanking, POOL_RERUN_DEBOUNCE_MS, poolQuestionsVisitTrigger, POOL_VISIT_MINING_DEBOUNCE_MS, } from "../discriminator/discriminator.env.js";
24
+ // discovery env accessors
25
+ export { discoveryAllowedTypes, discoveryIntentMatchingEnabled, discoveryProfileMatchingEnabled, discoveryProfileSource, resetDiscoveryEnvWarningsForTests, } from "../discovery.env.js";
24
26
  export { buildPoolAdjustment, planPoolAdjustments, mergePoolAdjustment, } from "../discriminator/discriminator.adjustments.js";
25
27
  export { synthesizePoolQuestion, selectQuestionDiscriminators, toQuestionDiscriminator, BOTH_MATTER_LABEL, } from "../discriminator/discriminator.question.js";
26
28
  export { poolQuestionCycleKey, buildPoolQuestionPushMessage, } from "../discriminator/discriminator.push.js";
@@ -1482,6 +1482,25 @@ export interface Database {
1482
1482
  assertionText: string;
1483
1483
  similarity: number;
1484
1484
  }>>;
1485
+ /**
1486
+ * Cosine similarity search against user_context embeddings, scoped to shared networks.
1487
+ * Matches only per-network context rows (the global networkId-null row is never a
1488
+ * candidate), excluding the discovering user. Optional — lightweight-mode
1489
+ * context-to-context discovery no-ops when the adapter omits it.
1490
+ */
1491
+ searchUserContextsBySimilarity?(params: {
1492
+ embedding: number[];
1493
+ networkIds: string[];
1494
+ excludeUserId: string;
1495
+ limit: number;
1496
+ minScore?: number;
1497
+ }): Promise<Array<{
1498
+ contextId: string;
1499
+ userId: string;
1500
+ networkId: string;
1501
+ text: string;
1502
+ similarity: number;
1503
+ }>>;
1485
1504
  /**
1486
1505
  * Batched version of premise similarity search. Executes one bounded DB call
1487
1506
  * for all selected source premises instead of one query per source premise.
@@ -1911,7 +1930,7 @@ export type PremiseGraphDatabase = Pick<Database, 'createPremise' | 'getPremise'
1911
1930
  *
1912
1931
  * Access layer: Both UserDatabase + SystemDatabase (orchestrates all operations)
1913
1932
  */
1914
- export type ChatGraphCompositeDatabase = Pick<Database, 'getProfile' | 'getActiveIntents' | 'getActiveIntentsAcrossIndexes' | 'getIntentsInIndexForMember' | 'getUser' | 'updateUser' | 'getUserSocials' | 'setUserSocials' | 'saveProfile' | 'softDeleteGhost' | 'createIntent' | 'updateIntent' | 'archiveIntent' | 'createOpportunity' | 'createOpportunityIfNetworkEligible' | 'createOpportunityAndExpireIdsIfNetworkEligible' | 'persistIntentScopedOpportunityIfNetworkEligible' | 'updateOpportunityStatusIfNetworkEligible' | 'getOpportunity' | 'getOpportunitiesByIds' | 'opportunityExistsBetweenActors' | 'findOpportunitiesByActors' | 'getOpportunitiesForUser' | 'updateOpportunityStatus' | 'compensateTasklessNegotiatingOpportunity' | 'updateOpportunityActorApproval' | 'stampOpportunityActorAction' | 'getOrCreateDM' | 'getHydeDocument' | 'getHydeDocumentsForSource' | 'saveHydeDocument' | 'getIntent' | 'getPublicIndexesNotJoined' | 'getUserIndexIds' | 'getAssignmentNetworkMembershipsForUser' | 'getAssignmentNetworkIdsForUser' | 'getNetworkMemberships' | 'getNetworkMembership' | 'getActiveNetworkMembershipPairs' | 'getNetwork' | 'getNetworkWithPermissions' | 'getIntentForIndexing' | 'getNetworkMemberContext' | 'getNetworkAssignmentContext' | 'isIntentAssignedToIndex' | 'assignIntentToNetwork' | 'assignIntentToNetworkIfMember' | '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'>;
1933
+ export type ChatGraphCompositeDatabase = Pick<Database, 'getProfile' | 'getActiveIntents' | 'getActiveIntentsAcrossIndexes' | 'getIntentsInIndexForMember' | 'getUser' | 'updateUser' | 'getUserSocials' | 'setUserSocials' | 'saveProfile' | 'softDeleteGhost' | 'createIntent' | 'updateIntent' | 'archiveIntent' | 'createOpportunity' | 'createOpportunityIfNetworkEligible' | 'createOpportunityAndExpireIdsIfNetworkEligible' | 'persistIntentScopedOpportunityIfNetworkEligible' | 'updateOpportunityStatusIfNetworkEligible' | 'getOpportunity' | 'getOpportunitiesByIds' | 'opportunityExistsBetweenActors' | 'findOpportunitiesByActors' | 'getOpportunitiesForUser' | 'updateOpportunityStatus' | 'compensateTasklessNegotiatingOpportunity' | 'updateOpportunityActorApproval' | 'stampOpportunityActorAction' | 'getOrCreateDM' | 'getHydeDocument' | 'getHydeDocumentsForSource' | 'saveHydeDocument' | 'getIntent' | 'getPublicIndexesNotJoined' | 'getUserIndexIds' | 'getAssignmentNetworkMembershipsForUser' | 'getAssignmentNetworkIdsForUser' | 'getNetworkMemberships' | 'getNetworkMembership' | 'getActiveNetworkMembershipPairs' | 'getNetwork' | 'getNetworkWithPermissions' | 'getIntentForIndexing' | 'getNetworkMemberContext' | 'getNetworkAssignmentContext' | 'isIntentAssignedToIndex' | 'assignIntentToNetwork' | 'assignIntentToNetworkIfMember' | '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' | 'searchUserContextsBySimilarity'> & Pick<NegotiationQueries, 'getNegotiationTaskForOpportunity'>;
1915
1934
  /**
1916
1935
  * Database interface for Opportunity Graph operations.
1917
1936
  * Includes prep/scope (network membership, intents, index details), persist (create, dedupe),
@@ -1919,7 +1938,7 @@ export type ChatGraphCompositeDatabase = Pick<Database, 'getProfile' | 'getActiv
1919
1938
  *
1920
1939
  * Access layer: SystemDatabase (cross-user opportunity operations)
1921
1940
  */
1922
- export type OpportunityGraphDatabase = Pick<Database, 'getProfile' | 'createOpportunity' | 'createOpportunityIfNetworkEligible' | 'createOpportunityAndExpireIdsIfNetworkEligible' | 'persistIntentScopedOpportunityIfNetworkEligible' | 'updateOpportunityStatusIfNetworkEligible' | 'opportunityExistsBetweenActors' | 'findOpportunitiesByActors' | 'getUserIndexIds' | 'getNetworkMemberships' | 'getActiveNetworkMembershipPairs' | 'getActiveIntents' | 'getNetworkIdsForIntent' | 'getNetwork' | 'getNetworkMemberCount' | 'getIntentIndexScores' | 'getNetworkMemberContext' | 'getNetworkAssignmentContext' | 'getOpportunity' | 'getOpportunitiesForUser' | 'updateOpportunityStatus' | 'compensateTasklessNegotiatingOpportunity' | 'stampOpportunityActorAction' | 'updateOpportunityActorApproval' | 'isNetworkMember' | 'isIndexOwner' | 'getUser' | 'getOrCreateDM' | 'getIntent' | 'getPremise' | 'getPremisesForUser' | 'getPremisesForUserInNetworks' | 'searchPremisesBySimilarity' | 'searchPremisesBySimilarityBatch' | 'getUserContext' | 'getUserContexts' | 'searchIntentsByContextEmbedding' | 'getHydeDocumentsForSource' | 'getRecentlyRejectedOpportunityCounterparties'> & Pick<NegotiationQueries, 'getNegotiationTaskForOpportunity'>;
1941
+ export type OpportunityGraphDatabase = Pick<Database, 'getProfile' | 'createOpportunity' | 'createOpportunityIfNetworkEligible' | 'createOpportunityAndExpireIdsIfNetworkEligible' | 'persistIntentScopedOpportunityIfNetworkEligible' | 'updateOpportunityStatusIfNetworkEligible' | 'opportunityExistsBetweenActors' | 'findOpportunitiesByActors' | 'getUserIndexIds' | 'getNetworkMemberships' | 'getActiveNetworkMembershipPairs' | 'getActiveIntents' | 'getNetworkIdsForIntent' | 'getNetwork' | 'getNetworkMemberCount' | 'getIntentIndexScores' | 'getNetworkMemberContext' | 'getNetworkAssignmentContext' | 'getOpportunity' | 'getOpportunitiesForUser' | 'updateOpportunityStatus' | 'compensateTasklessNegotiatingOpportunity' | 'stampOpportunityActorAction' | 'updateOpportunityActorApproval' | 'isNetworkMember' | 'isIndexOwner' | 'getUser' | 'getOrCreateDM' | 'getIntent' | 'getPremise' | 'getPremisesForUser' | 'getPremisesForUserInNetworks' | 'searchPremisesBySimilarity' | 'searchPremisesBySimilarityBatch' | 'getUserContext' | 'getUserContexts' | 'searchIntentsByContextEmbedding' | 'searchUserContextsBySimilarity' | 'getHydeDocumentsForSource' | 'getRecentlyRejectedOpportunityCounterparties'> & Pick<NegotiationQueries, 'getNegotiationTaskForOpportunity'>;
1923
1942
  /**
1924
1943
  * Negotiation-specific query operations not covered by generic
1925
1944
  * conversation/task primitives.
@@ -20,16 +20,30 @@ export interface HydeSearchOptions {
20
20
  limit?: number;
21
21
  /** Minimum cosine similarity for intent searches (default 0.40). */
22
22
  minScore?: number;
23
+ /**
24
+ * Discovery corpus gating, composed by the caller (defaults preserve legacy behavior).
25
+ * Omitted fields default to: intents true, profile true, profileCorpus 'premise'.
26
+ */
27
+ corpusGating?: {
28
+ /** Search the intents corpus. */
29
+ intents?: boolean;
30
+ /** Search the active profile corpus. */
31
+ profile?: boolean;
32
+ /** Which corpus backs 'profiles' lens hints and profile searches. */
33
+ profileCorpus?: 'premise' | 'user_context';
34
+ };
23
35
  }
24
- /** A single candidate from HyDE search (intent or premise), with score and which lens matched. */
36
+ /** A single candidate from HyDE search (intent, premise, or user_context), with score and which lens matched. */
25
37
  export interface HydeCandidate {
26
- type: 'intent' | 'premise';
38
+ type: 'intent' | 'premise' | 'user_context';
27
39
  id: string;
28
40
  userId: string;
29
41
  score: number;
30
42
  /** Free-text lens label that produced this match. */
31
43
  matchedVia: string;
32
44
  networkId: string;
45
+ /** Candidate document text (populated for user_context matches; used as candidatePayload). */
46
+ text?: string;
33
47
  /** Set after merge when user matched via multiple lenses. */
34
48
  matchedLenses?: string[];
35
49
  }
@@ -86,47 +86,50 @@ export declare const NetworkAssignmentMetadataSchema: z.ZodObject<{
86
86
  createdAt?: string | undefined;
87
87
  }>;
88
88
  export type NetworkAssignmentMetadata = z.infer<typeof NetworkAssignmentMetadataSchema>;
89
- export declare const OpportunityEvidenceKindSchema: z.ZodEnum<["query_intent", "query_premise", "premise_similarity", "context_to_intent", "profile"]>;
89
+ export declare const OpportunityEvidenceKindSchema: z.ZodEnum<["query_intent", "query_premise", "query_context", "premise_similarity", "context_similarity", "context_to_intent", "profile"]>;
90
90
  export type OpportunityEvidenceKind = z.infer<typeof OpportunityEvidenceKindSchema>;
91
91
  export declare const OpportunityEvidenceSchema: z.ZodObject<{
92
- kind: z.ZodEnum<["query_intent", "query_premise", "premise_similarity", "context_to_intent", "profile"]>;
92
+ kind: z.ZodEnum<["query_intent", "query_premise", "query_context", "premise_similarity", "context_similarity", "context_to_intent", "profile"]>;
93
93
  networkId: z.ZodString;
94
94
  score: z.ZodOptional<z.ZodNumber>;
95
95
  lens: z.ZodOptional<z.ZodString>;
96
- discoverySource: z.ZodOptional<z.ZodEnum<["query", "premise-similarity", "context-to-intent"]>>;
96
+ discoverySource: z.ZodOptional<z.ZodEnum<["query", "premise-similarity", "context-to-intent", "context-similarity"]>>;
97
97
  matchedStrategies: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
98
98
  sourcePremiseId: z.ZodOptional<z.ZodString>;
99
99
  candidatePremiseId: z.ZodOptional<z.ZodString>;
100
100
  candidateIntentId: z.ZodOptional<z.ZodString>;
101
101
  sourceContextId: z.ZodOptional<z.ZodString>;
102
+ candidateContextId: z.ZodOptional<z.ZodString>;
102
103
  payload: z.ZodOptional<z.ZodString>;
103
104
  summary: z.ZodOptional<z.ZodString>;
104
105
  assertionText: z.ZodOptional<z.ZodString>;
105
106
  }, "strip", z.ZodTypeAny, {
106
- kind: "query_intent" | "query_premise" | "premise_similarity" | "context_to_intent" | "profile";
107
+ kind: "query_intent" | "query_premise" | "query_context" | "premise_similarity" | "context_similarity" | "context_to_intent" | "profile";
107
108
  networkId: string;
108
109
  score?: number | undefined;
109
110
  lens?: string | undefined;
110
- discoverySource?: "query" | "premise-similarity" | "context-to-intent" | undefined;
111
+ discoverySource?: "query" | "premise-similarity" | "context-to-intent" | "context-similarity" | undefined;
111
112
  matchedStrategies?: string[] | undefined;
112
113
  sourcePremiseId?: string | undefined;
113
114
  candidatePremiseId?: string | undefined;
114
115
  candidateIntentId?: string | undefined;
115
116
  sourceContextId?: string | undefined;
117
+ candidateContextId?: string | undefined;
116
118
  payload?: string | undefined;
117
119
  summary?: string | undefined;
118
120
  assertionText?: string | undefined;
119
121
  }, {
120
- kind: "query_intent" | "query_premise" | "premise_similarity" | "context_to_intent" | "profile";
122
+ kind: "query_intent" | "query_premise" | "query_context" | "premise_similarity" | "context_similarity" | "context_to_intent" | "profile";
121
123
  networkId: string;
122
124
  score?: number | undefined;
123
125
  lens?: string | undefined;
124
- discoverySource?: "query" | "premise-similarity" | "context-to-intent" | undefined;
126
+ discoverySource?: "query" | "premise-similarity" | "context-to-intent" | "context-similarity" | undefined;
125
127
  matchedStrategies?: string[] | undefined;
126
128
  sourcePremiseId?: string | undefined;
127
129
  candidatePremiseId?: string | undefined;
128
130
  candidateIntentId?: string | undefined;
129
131
  sourceContextId?: string | undefined;
132
+ candidateContextId?: string | undefined;
130
133
  payload?: string | undefined;
131
134
  summary?: string | undefined;
132
135
  assertionText?: string | undefined;
@@ -33,7 +33,9 @@ export const NetworkAssignmentMetadataSchema = z.object({
33
33
  export const OpportunityEvidenceKindSchema = z.enum([
34
34
  "query_intent",
35
35
  "query_premise",
36
+ "query_context",
36
37
  "premise_similarity",
38
+ "context_similarity",
37
39
  "context_to_intent",
38
40
  "profile",
39
41
  ]);
@@ -42,12 +44,13 @@ export const OpportunityEvidenceSchema = z.object({
42
44
  networkId: z.string(),
43
45
  score: z.number().min(0).max(1).optional(),
44
46
  lens: z.string().optional(),
45
- discoverySource: z.enum(["query", "premise-similarity", "context-to-intent"]).optional(),
47
+ discoverySource: z.enum(["query", "premise-similarity", "context-to-intent", "context-similarity"]).optional(),
46
48
  matchedStrategies: z.array(z.string()).optional(),
47
49
  sourcePremiseId: z.string().optional(),
48
50
  candidatePremiseId: z.string().optional(),
49
51
  candidateIntentId: z.string().optional(),
50
52
  sourceContextId: z.string().optional(),
53
+ candidateContextId: z.string().optional(),
51
54
  payload: z.string().optional(),
52
55
  summary: z.string().optional(),
53
56
  assertionText: z.string().optional(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indexnetwork/protocol",
3
- "version": "8.1.0-rc.421.1",
3
+ "version": "8.2.0-rc.423.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -39,6 +39,7 @@
39
39
  "eval:profile": "bun --env-file=../../.env.test ./eval/profile/profile.eval.ts",
40
40
  "eval:opportunity": "bun --env-file=../../.env.test ./eval/opportunity/opportunity.eval.ts",
41
41
  "eval:clarification": "bun --env-file=../../.env.test ./eval/clarification/clarification.eval.ts",
42
+ "eval:discovery-retrieval": "bun --env-file=../../.env.test ./eval/discovery-retrieval/discovery-retrieval.eval.ts",
42
43
  "eval:canary": "bun --env-file=../../.env.test ./eval/canary/canary.eval.ts",
43
44
  "eval:stance": "bun --env-file=../../.env.test ./eval/stance/stance.eval.ts",
44
45
  "eval:view": "bun ./eval/viewer/viewer.eval.ts",