@indexnetwork/protocol 14.3.2-rc.477.1 → 17.0.0-rc.479.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 (184) hide show
  1. package/CHANGELOG.md +141 -0
  2. package/IMPLEMENTATION.md +50 -52
  3. package/STABILITY.md +3 -3
  4. package/dist/chat/chat.agent.js +2 -3
  5. package/dist/chat/chat.graph.d.ts +41 -1
  6. package/dist/chat/chat.graph.js +108 -127
  7. package/dist/chat/negotiator.persona.d.ts +1 -1
  8. package/dist/chat/negotiator.persona.js +1 -4
  9. package/dist/chat/negotiator.prompt.js +1 -2
  10. package/dist/chat/onboarding.persona.js +0 -1
  11. package/dist/chat/reporter.persona.js +0 -1
  12. package/dist/chat/signal.persona.js +0 -1
  13. package/dist/contacts/application/contact.tools.d.ts +6 -9
  14. package/dist/contacts/application/contact.tools.js +11 -92
  15. package/dist/contacts/application/index.d.ts +2 -14
  16. package/dist/contacts/application/index.js +2 -13
  17. package/dist/contacts/domain/contact.types.d.ts +0 -23
  18. package/dist/contacts/domain/index.d.ts +2 -6
  19. package/dist/contacts/index.d.ts +1 -1
  20. package/dist/contacts/index.js +1 -1
  21. package/dist/contacts/ports/contact.repository.port.d.ts +5 -12
  22. package/dist/contacts/ports/contact.repository.port.js +4 -6
  23. package/dist/contacts/ports/contact.tools.port.d.ts +1 -3
  24. package/dist/contacts/ports/contact.tools.port.js +1 -2
  25. package/dist/contacts/ports/index.d.ts +1 -1
  26. package/dist/contacts/ports/index.js +1 -1
  27. package/dist/discovery/hyde.frame.d.ts +4 -4
  28. package/dist/discovery/hyde.graph.d.ts +71 -12
  29. package/dist/discovery/hyde.graph.js +337 -335
  30. package/dist/discovery/lens.inferrer.d.ts +6 -6
  31. package/dist/enrichment/enrichment.graph.d.ts +127 -9
  32. package/dist/enrichment/enrichment.graph.js +633 -655
  33. package/dist/enrichment/enrichment.state.d.ts +1 -1
  34. package/dist/enrichment/enrichment.tools.context-read.d.ts +10 -0
  35. package/dist/enrichment/enrichment.tools.context-read.js +353 -0
  36. package/dist/enrichment/enrichment.tools.context-write.d.ts +9 -0
  37. package/dist/enrichment/enrichment.tools.context-write.js +417 -0
  38. package/dist/enrichment/enrichment.tools.d.ts +11 -1
  39. package/dist/enrichment/enrichment.tools.helpers.d.ts +139 -0
  40. package/dist/enrichment/enrichment.tools.helpers.js +234 -0
  41. package/dist/enrichment/enrichment.tools.js +16 -975
  42. package/dist/index.d.ts +27 -50
  43. package/dist/index.js +17 -28
  44. package/dist/intents/application/intent.graph.d.ts +71 -67
  45. package/dist/intents/application/intent.graph.execute.d.ts +59 -0
  46. package/dist/intents/application/intent.graph.execute.js +301 -0
  47. package/dist/intents/application/intent.graph.infer.d.ts +44 -0
  48. package/dist/intents/application/intent.graph.infer.js +97 -0
  49. package/dist/intents/application/intent.graph.js +96 -888
  50. package/dist/intents/application/intent.graph.reconcile.d.ts +71 -0
  51. package/dist/intents/application/intent.graph.reconcile.js +274 -0
  52. package/dist/intents/application/intent.graph.shared.d.ts +70 -0
  53. package/dist/intents/application/intent.graph.shared.js +153 -0
  54. package/dist/intents/domain/intent.state.d.ts +1 -1
  55. package/dist/maintenance/maintenance.graph.d.ts +66 -3
  56. package/dist/maintenance/maintenance.graph.js +155 -156
  57. package/dist/mcp/mcp.authorization-policy.d.ts +24 -28
  58. package/dist/mcp/mcp.authorization-policy.js +14 -34
  59. package/dist/mcp/mcp.server.d.ts +3 -3
  60. package/dist/mcp/mcp.server.js +14 -20
  61. package/dist/negotiations/application/negotiation.candidates.d.ts +83 -0
  62. package/dist/negotiations/application/negotiation.candidates.js +162 -0
  63. package/dist/negotiations/application/negotiation.graph.d.ts +91 -157
  64. package/dist/negotiations/application/negotiation.graph.finalize.d.ts +5 -0
  65. package/dist/negotiations/application/negotiation.graph.finalize.js +280 -0
  66. package/dist/negotiations/application/negotiation.graph.init.d.ts +54 -0
  67. package/dist/negotiations/application/negotiation.graph.init.js +227 -0
  68. package/dist/negotiations/application/negotiation.graph.js +69 -1388
  69. package/dist/negotiations/application/negotiation.graph.screen.d.ts +23 -0
  70. package/dist/negotiations/application/negotiation.graph.screen.js +108 -0
  71. package/dist/negotiations/application/negotiation.graph.shared.d.ts +75 -0
  72. package/dist/negotiations/application/negotiation.graph.shared.js +125 -0
  73. package/dist/negotiations/application/negotiation.graph.turn.d.ts +105 -0
  74. package/dist/negotiations/application/negotiation.graph.turn.js +484 -0
  75. package/dist/negotiations/domain/negotiation.state.d.ts +1 -1
  76. package/dist/negotiations/domain/negotiation.state.js +0 -1
  77. package/dist/networks/application/indexer.graph.d.ts +165 -7
  78. package/dist/networks/application/indexer.graph.js +339 -388
  79. package/dist/networks/application/indexer.state.d.ts +1 -1
  80. package/dist/networks/application/membership.graph.d.ts +83 -5
  81. package/dist/networks/application/membership.graph.js +177 -207
  82. package/dist/networks/application/network.graph.d.ts +148 -5
  83. package/dist/networks/application/network.graph.js +249 -278
  84. package/dist/networks/domain/membership.state.d.ts +1 -1
  85. package/dist/networks/domain/network.state.d.ts +1 -1
  86. package/dist/opportunities/application/delivery-card.cache.d.ts +1 -1
  87. package/dist/opportunities/application/delivery-card.cache.js +2 -2
  88. package/dist/opportunities/application/index.d.ts +2 -2
  89. package/dist/opportunities/application/index.js +2 -2
  90. package/dist/opportunities/application/opportunity.evaluator.js +1 -1
  91. package/dist/opportunities/application/opportunity.graph.d.ts +686 -473
  92. package/dist/opportunities/application/opportunity.graph.discovery-strategies.d.ts +109 -0
  93. package/dist/opportunities/application/opportunity.graph.discovery-strategies.js +451 -0
  94. package/dist/opportunities/application/opportunity.graph.discovery.d.ts +69 -0
  95. package/dist/opportunities/application/opportunity.graph.discovery.js +397 -0
  96. package/dist/opportunities/application/opportunity.graph.evaluation.d.ts +82 -0
  97. package/dist/opportunities/application/opportunity.graph.evaluation.js +608 -0
  98. package/dist/opportunities/application/opportunity.graph.js +120 -3690
  99. package/dist/opportunities/application/opportunity.graph.modes.d.ts +538 -0
  100. package/dist/opportunities/application/opportunity.graph.modes.js +538 -0
  101. package/dist/opportunities/application/opportunity.graph.negotiate.d.ts +109 -0
  102. package/dist/opportunities/application/opportunity.graph.negotiate.js +392 -0
  103. package/dist/opportunities/application/opportunity.graph.persist-node.d.ts +93 -0
  104. package/dist/opportunities/application/opportunity.graph.persist-node.js +765 -0
  105. package/dist/opportunities/application/opportunity.graph.prep.d.ts +150 -0
  106. package/dist/opportunities/application/opportunity.graph.prep.js +381 -0
  107. package/dist/opportunities/application/opportunity.graph.shared.d.ts +173 -0
  108. package/dist/opportunities/application/opportunity.graph.shared.js +199 -0
  109. package/dist/opportunities/application/opportunity.presentation.d.ts +399 -0
  110. package/dist/opportunities/application/{opportunity.presenter.js → opportunity.presentation.js} +735 -9
  111. package/dist/opportunities/application/opportunity.tools.cards.d.ts +152 -0
  112. package/dist/opportunities/application/opportunity.tools.cards.js +235 -0
  113. package/dist/opportunities/application/opportunity.tools.d.ts +8 -114
  114. package/dist/opportunities/application/opportunity.tools.js +28 -711
  115. package/dist/opportunities/application/opportunity.tools.list.d.ts +10 -0
  116. package/dist/opportunities/application/opportunity.tools.list.js +493 -0
  117. package/dist/opportunities/domain/index.d.ts +3 -3
  118. package/dist/opportunities/domain/index.js +3 -3
  119. package/dist/opportunities/domain/opportunity.state.d.ts +19 -19
  120. package/dist/opportunities/index.d.ts +6 -6
  121. package/dist/opportunities/index.js +4 -4
  122. package/dist/opportunities/ports/opportunity.tools.port.d.ts +1 -1
  123. package/dist/opportunities/radar/radar.graph.d.ts +57 -13
  124. package/dist/opportunities/radar/radar.graph.js +470 -471
  125. package/dist/premises/premise.graph.d.ts +88 -20
  126. package/dist/premises/premise.graph.js +207 -218
  127. package/dist/questions/domain/question.schema.d.ts +40 -40
  128. package/dist/shared/agent/tool.factory.js +0 -8
  129. package/dist/shared/agent/tool.helpers.d.ts +21 -45
  130. package/dist/shared/agent/tool.helpers.js +1 -2
  131. package/dist/shared/agent/tool.registry.d.ts +4 -3
  132. package/dist/shared/agent/tool.registry.js +2 -4
  133. package/dist/shared/agent/tool.runtime.js +0 -2
  134. package/dist/shared/agent/utility.tools.js +9 -13
  135. package/dist/shared/interfaces/database.capabilities.d.ts +100 -0
  136. package/dist/shared/interfaces/database.capabilities.js +7 -0
  137. package/dist/shared/interfaces/database.entities.d.ts +533 -0
  138. package/dist/shared/interfaces/database.entities.js +10 -0
  139. package/dist/shared/interfaces/database.identity-queries.d.ts +294 -0
  140. package/dist/shared/interfaces/database.identity-queries.js +4 -0
  141. package/dist/shared/interfaces/database.interface.d.ts +15 -2277
  142. package/dist/shared/interfaces/database.interface.js +8 -0
  143. package/dist/shared/interfaces/database.member-queries.d.ts +221 -0
  144. package/dist/shared/interfaces/database.member-queries.js +4 -0
  145. package/dist/shared/interfaces/database.negotiation.d.ts +305 -0
  146. package/dist/shared/interfaces/database.negotiation.js +26 -0
  147. package/dist/shared/interfaces/database.network-queries.d.ts +277 -0
  148. package/dist/shared/interfaces/database.network-queries.js +4 -0
  149. package/dist/shared/interfaces/database.opportunity-queries.d.ts +285 -0
  150. package/dist/shared/interfaces/database.opportunity-queries.js +4 -0
  151. package/dist/shared/interfaces/database.port.d.ts +322 -0
  152. package/dist/shared/interfaces/database.port.js +29 -0
  153. package/dist/shared/schemas/discovery-question.schema.d.ts +14 -14
  154. package/dist/shared/schemas/negotiation-digest.schema.d.ts +2 -2
  155. package/package.json +2 -15
  156. package/dist/contacts/application/contact.inviter.d.ts +0 -49
  157. package/dist/contacts/application/contact.inviter.js +0 -64
  158. package/dist/integrations/application/index.d.ts +0 -14
  159. package/dist/integrations/application/index.js +0 -14
  160. package/dist/integrations/application/integration.tools.d.ts +0 -27
  161. package/dist/integrations/application/integration.tools.js +0 -98
  162. package/dist/integrations/domain/index.d.ts +0 -16
  163. package/dist/integrations/domain/index.js +0 -1
  164. package/dist/integrations/domain/integration.types.d.ts +0 -51
  165. package/dist/integrations/domain/integration.types.js +0 -9
  166. package/dist/integrations/index.d.ts +0 -10
  167. package/dist/integrations/index.js +0 -8
  168. package/dist/integrations/ports/index.d.ts +0 -25
  169. package/dist/integrations/ports/index.js +0 -23
  170. package/dist/integrations/ports/integration.adapter.port.d.ts +0 -62
  171. package/dist/integrations/ports/integration.adapter.port.js +0 -15
  172. package/dist/integrations/ports/integration.importer.port.d.ts +0 -31
  173. package/dist/integrations/ports/integration.importer.port.js +0 -15
  174. package/dist/integrations/ports/integration.tools.port.d.ts +0 -25
  175. package/dist/integrations/ports/integration.tools.port.js +0 -18
  176. package/dist/opportunities/application/opportunity.card-presentation.d.ts +0 -44
  177. package/dist/opportunities/application/opportunity.card-presentation.js +0 -93
  178. package/dist/opportunities/application/opportunity.presenter.d.ts +0 -156
  179. package/dist/opportunities/domain/opportunity.presentation-cache.d.ts +0 -5
  180. package/dist/opportunities/domain/opportunity.presentation-cache.js +0 -11
  181. package/dist/opportunities/domain/opportunity.presentation.d.ts +0 -76
  182. package/dist/opportunities/domain/opportunity.presentation.js +0 -516
  183. package/dist/opportunities/domain/opportunity.safe-presentation.d.ts +0 -104
  184. package/dist/opportunities/domain/opportunity.safe-presentation.js +0 -102
@@ -0,0 +1,322 @@
1
+ /**
2
+ * The database port itself, plus the two access-scoped views over it.
3
+ *
4
+ * `Database` is the union of the four query groups; splitting it into composed
5
+ * interfaces keeps each group readable without changing the type one bit —
6
+ * every `Pick<Database, ...>` alias still resolves exactly as before.
7
+ */
8
+ import type { UserIdentity } from '../schemas/identity.schema.js';
9
+ import type { NetworkAssignmentMetadata } from '../schemas/network-assignment.schema.js';
10
+ import type { ActiveIntent, ArchiveResult, CreateHydeDocumentData, CreateIntentData, CreateOpportunityData, CreatedIntent, HydeDocument, HydeSourceType, Id, IndexMemberDetails, IndexedIntentDetails, IntentRecord, NetworkAssignmentContext, NetworkMembership, OnboardingState, Opportunity, OpportunityQueryOptions, OpportunityStatus, OwnedIndex, SimilarIntent, SimilarIntentSearchOptions, UpdateIndexSettingsData, UpdateIntentData, UserRecord, UserSocial } from './database.entities.js';
11
+ import type { DatabaseIdentityQueries } from './database.identity-queries.js';
12
+ import type { DatabaseMemberQueries } from './database.member-queries.js';
13
+ import type { DatabaseNetworkQueries } from './database.network-queries.js';
14
+ import type { DatabaseOpportunityQueries } from './database.opportunity-queries.js';
15
+ /**
16
+ * Abstract database interface for performing specific domain operations.
17
+ * Decouples the protocol layer from the infrastructure layer.
18
+ */
19
+ export interface Database extends DatabaseIdentityQueries, DatabaseNetworkQueries, DatabaseOpportunityQueries, DatabaseMemberQueries {
20
+ }
21
+ /**
22
+ * Context-bound database for accessing the authenticated user's own resources.
23
+ * Created with authUserId bound at construction; no userId parameter needed on methods.
24
+ *
25
+ * **NOT network-scoped**: Returns ALL of the user's own resources regardless of index.
26
+ * This is critical for the IntentReconciler which needs the full picture for deduplication.
27
+ *
28
+ * Use via `createUserDatabase(db, authUserId)` factory function.
29
+ */
30
+ export interface AgentActivitySummary {
31
+ /** The requested reporting window, in hours. */
32
+ sinceHours: number;
33
+ /** Number of the user's own non-archived ACTIVE intents. */
34
+ liveSignalsWatched: number;
35
+ /** Opportunities created in the window and linked to one of the user's intents. */
36
+ opportunitiesSurfaced: number;
37
+ /** Opportunity counts grouped by the user's own signal. */
38
+ opportunitiesBySignal: Array<{
39
+ intentId: string;
40
+ title: string;
41
+ count: number;
42
+ }>;
43
+ /** Current, non-expired questions waiting for the user, grouped by affected mode (QuestionMode values). Meta-network. */
44
+ pendingQuestionsByMode: Record<string, number>;
45
+ /** Questions answered by the user during the window, grouped by affected mode (QuestionMode values). Meta-network. */
46
+ answeredQuestionsByMode: Record<string, number>;
47
+ /** Distinct opportunity negotiations started during the window. */
48
+ negotiationsStarted: number;
49
+ /** Distinct opportunity negotiations completed during the window. */
50
+ negotiationsCompleted: number;
51
+ }
52
+ export interface UserDatabase {
53
+ /** The bound authenticated user ID */
54
+ readonly authUserId: string;
55
+ /** Get the authenticated user's profile. */
56
+ getProfile(): Promise<UserIdentity | null>;
57
+ /** Get the authenticated user's profile with row ID. */
58
+ getProfileByUserId(): Promise<(UserIdentity & {
59
+ id: string;
60
+ }) | null>;
61
+ /** Save/update the authenticated user's profile. */
62
+ saveProfile(profile: UserIdentity): Promise<void>;
63
+ /** Delete the authenticated user's profile. */
64
+ deleteProfile(): Promise<void>;
65
+ /** Get the authenticated user's basic record (name, email, socials). */
66
+ getUser(): Promise<UserRecord | null>;
67
+ /** Update the authenticated user's account fields. */
68
+ updateUser(data: {
69
+ name?: string;
70
+ intro?: string;
71
+ location?: string;
72
+ onboarding?: OnboardingState;
73
+ }): Promise<UserRecord | null>;
74
+ getUserSocials(): Promise<UserSocial[]>;
75
+ setUserSocials(socials: {
76
+ label: string;
77
+ value: string;
78
+ }[]): Promise<void>;
79
+ /** Get ALL active intents for the authenticated user (not index-filtered). */
80
+ getActiveIntents(): Promise<ActiveIntent[]>;
81
+ /**
82
+ * Case-insensitive substring search over the authenticated user's own
83
+ * active intents. Matches against `payload` and `summary`. Most recent first.
84
+ */
85
+ searchOwnIntents(q: string, limit: number): Promise<Array<{
86
+ id: string;
87
+ payload: string;
88
+ summary: string | null;
89
+ createdAt: Date;
90
+ }>>;
91
+ /** Get a single intent by ID (ownership enforced). */
92
+ getIntent(intentId: string): Promise<IntentRecord | null>;
93
+ /** Create a new intent for the authenticated user. */
94
+ createIntent(data: Omit<CreateIntentData, 'userId'>): Promise<CreatedIntent>;
95
+ /** Update an intent owned by the authenticated user. */
96
+ updateIntent(intentId: string, data: UpdateIntentData): Promise<CreatedIntent | null>;
97
+ /** Archive an intent owned by the authenticated user. */
98
+ archiveIntent(intentId: string): Promise<ArchiveResult>;
99
+ /** Find similar intents among the user's own intents (for deduplication). */
100
+ findSimilarIntents(embedding: number[], options?: SimilarIntentSearchOptions): Promise<SimilarIntent[]>;
101
+ /** Get intent fields for indexing (own intent). */
102
+ getIntentForIndexing(intentId: string): Promise<{
103
+ id: string;
104
+ payload: string;
105
+ userId: string;
106
+ sourceType: string | null;
107
+ sourceId: string | null;
108
+ } | null>;
109
+ /** Associate an intent with networks. */
110
+ associateIntentWithNetworks(intentId: string, networkIds: string[]): Promise<void>;
111
+ /** Assign an intent to an index. */
112
+ assignIntentToNetwork(intentId: string, networkId: string, relevancyScore?: number, assignmentMetadata?: NetworkAssignmentMetadata): Promise<void>;
113
+ /** Unassign an intent from an index. */
114
+ unassignIntentFromIndex(intentId: string, networkId: string): Promise<void>;
115
+ /** Get network IDs for an intent. */
116
+ getNetworkIdsForIntent(intentId: string): Promise<string[]>;
117
+ /** Check if intent is assigned to index. */
118
+ isIntentAssignedToIndex(intentId: string, networkId: string): Promise<boolean>;
119
+ /** Get all network memberships for the authenticated user. */
120
+ getNetworkMemberships(): Promise<NetworkMembership[]>;
121
+ /** Get network IDs with auto-assign enabled for the authenticated user. */
122
+ getUserIndexIds(): Promise<string[]>;
123
+ /** Get indexes owned by the authenticated user. */
124
+ getOwnedIndexes(): Promise<OwnedIndex[]>;
125
+ /** Get a specific network membership for the authenticated user. */
126
+ getNetworkMembership(networkId: string): Promise<NetworkMembership | null>;
127
+ /** Get index + member context for the authenticated user (for auto-assign). */
128
+ getNetworkMemberContext(networkId: string): Promise<NetworkAssignmentContext | null>;
129
+ /** Get index + member context for the authenticated user without auto-assign gating. */
130
+ getNetworkAssignmentContext?(networkId: string): Promise<NetworkAssignmentContext | null>;
131
+ /** Create a new index (user becomes owner). */
132
+ createNetwork(data: {
133
+ title: string;
134
+ prompt?: string | null;
135
+ imageUrl?: string | null;
136
+ joinPolicy?: 'anyone' | 'invite_only';
137
+ }): Promise<{
138
+ id: string;
139
+ title: string;
140
+ prompt: string | null;
141
+ imageUrl: string | null;
142
+ permissions: {
143
+ joinPolicy: 'anyone' | 'invite_only';
144
+ invitationLink: {
145
+ code: string;
146
+ } | null;
147
+ };
148
+ }>;
149
+ /** Update index settings (owner only). */
150
+ updateIndexSettings(networkId: string, data: UpdateIndexSettingsData): Promise<OwnedIndex>;
151
+ /** Soft-delete a network (owner only). */
152
+ softDeleteNetwork(networkId: string): Promise<void>;
153
+ /** Get public networks (joinPolicy 'anyone') that the user has not joined. */
154
+ getPublicIndexesNotJoined(): Promise<{
155
+ networks: Array<{
156
+ id: string;
157
+ title: string;
158
+ prompt: string | null;
159
+ memberCount: number;
160
+ owner: {
161
+ id: string;
162
+ name: string;
163
+ avatar: string | null;
164
+ } | null;
165
+ }>;
166
+ }>;
167
+ /** Join a public network (validates joinPolicy === 'anyone'). */
168
+ joinPublicNetwork(networkId: string): Promise<{
169
+ success: boolean;
170
+ alreadyMember?: boolean;
171
+ }>;
172
+ /**
173
+ * Summarize the authenticated user's own agent activity without counterparty rows.
174
+ * When `networkId` is present (a network agent's bound community), the
175
+ * network-bound aggregates (opportunity and negotiation counts) are narrowed
176
+ * to that community inside the query; own-signal and question aggregates are
177
+ * meta-network and stay global.
178
+ */
179
+ getAgentActivitySummary(input: {
180
+ sinceHours: number;
181
+ networkId?: string;
182
+ }): Promise<AgentActivitySummary>;
183
+ /** Get opportunities where the authenticated user is an actor. */
184
+ getOpportunitiesForUser(options?: OpportunityQueryOptions): Promise<Opportunity[]>;
185
+ /** Get a specific opportunity (if user is an actor). */
186
+ getOpportunity(id: string): Promise<Opportunity | null>;
187
+ /** Update an opportunity's status (if user is an actor). acceptedBy is derived from the auth context. */
188
+ updateOpportunityStatus(id: string, status: OpportunityStatus): Promise<Opportunity | null>;
189
+ /** Accept sibling opportunities between the authenticated user and another actor. */
190
+ acceptSiblingOpportunities(counterpartUserId: string, excludeOpportunityId: string): Promise<string[]>;
191
+ /** Get a HyDE document for the user's own source. */
192
+ getHydeDocument(sourceType: HydeSourceType, sourceId: string, strategy: string): Promise<HydeDocument | null>;
193
+ /** Get all HyDE documents for the user's own source. */
194
+ getHydeDocumentsForSource(sourceType: HydeSourceType, sourceId: string): Promise<HydeDocument[]>;
195
+ /** Save a HyDE document for the user's own source. */
196
+ saveHydeDocument(data: CreateHydeDocumentData): Promise<HydeDocument>;
197
+ /** Delete HyDE documents for the user's own source. */
198
+ deleteHydeDocumentsForSource(sourceType: HydeSourceType, sourceId: string): Promise<number>;
199
+ }
200
+ /**
201
+ * Context-bound database for LLM/system operations that access cross-user resources.
202
+ * Created with authUserId + indexScope[]; validates membership before access.
203
+ *
204
+ * **Network-scoped**: All cross-user operations are restricted to users/resources
205
+ * within the bound indexScope[]. This prevents the LLM from accessing arbitrary users' data.
206
+ *
207
+ * Use via `createSystemDatabase(db, authUserId, indexScope)` factory function.
208
+ */
209
+ export interface SystemDatabase {
210
+ /** The bound authenticated user ID */
211
+ readonly authUserId: string;
212
+ /** The indexes the authenticated user has access to (determines cross-user scope) */
213
+ readonly indexScope: string[];
214
+ /** Get a user's profile (requires shared network membership). */
215
+ getProfile(userId: string): Promise<UserIdentity | null>;
216
+ /** Get a user's basic record (requires shared network membership). */
217
+ getUser(userId: string): Promise<UserRecord | null>;
218
+ /** Get all intents in an index (cross-user, requires membership). */
219
+ getIntentsInIndex(networkId: string, options?: {
220
+ limit?: number;
221
+ offset?: number;
222
+ }): Promise<IndexedIntentDetails[]>;
223
+ /** Get a specific user's intents in an index (requires shared membership). */
224
+ getUserIntentsInIndex(userId: string, networkId: string): Promise<ActiveIntent[]>;
225
+ /**
226
+ * Get the caller's own active intents across a set of indexes.
227
+ * Returns intents owned by `userId` that are linked (via intent_networks)
228
+ * to at least one of `indexIds`. Used by network-scoped agents to honor
229
+ * indexScope without falling back to global getActiveIntents (which would
230
+ * include intents in indexes outside scope).
231
+ *
232
+ * @param userId - The intent owner (always the caller).
233
+ * @param indexIds - The set of network IDs to filter on. Empty → empty result.
234
+ * @returns Active intents owned by userId in any of indexIds, deduped by intent id.
235
+ */
236
+ getActiveIntentsAcrossIndexes(userId: string, indexIds: string[]): Promise<ActiveIntent[]>;
237
+ /** Get a single intent by ID (if in scope). */
238
+ getIntent(intentId: string): Promise<IntentRecord | null>;
239
+ /** Find similar intents across users within the network scope. */
240
+ findSimilarIntentsInScope(embedding: number[], options?: SimilarIntentSearchOptions): Promise<SimilarIntent[]>;
241
+ /** Check if a user is a member of an index. */
242
+ isNetworkMember(networkId: string, userId: string): Promise<boolean>;
243
+ /** Check if a user is an owner of an index. */
244
+ isIndexOwner(networkId: string, userId: string): Promise<boolean>;
245
+ /** Get all members of an index (requires membership). */
246
+ getNetworkMembers(networkId: string): Promise<IndexMemberDetails[]>;
247
+ /** Get all members across all networks in scope (deduplicated). */
248
+ getMembersFromScope(): Promise<{
249
+ userId: Id<'users'>;
250
+ name: string;
251
+ avatar: string | null;
252
+ }[]>;
253
+ /** Add a user to an index (requires ownership or 'anyone' policy). */
254
+ addMemberToNetwork(networkId: string, userId: string, role: 'owner' | 'member'): Promise<{
255
+ success: boolean;
256
+ alreadyMember?: boolean;
257
+ }>;
258
+ /** Remove a user from an index (requires ownership). Cannot remove the owner. */
259
+ removeMemberFromIndex(networkId: string, userId: string): Promise<{
260
+ success: boolean;
261
+ wasOwner?: boolean;
262
+ notMember?: boolean;
263
+ }>;
264
+ /** Get index info by ID with core fields (requires scope). */
265
+ getNetwork(networkId: string): Promise<{
266
+ id: string;
267
+ title: string;
268
+ prompt?: string | null;
269
+ type?: string;
270
+ metadata?: Record<string, unknown> | null;
271
+ permissions?: Record<string, unknown> | null;
272
+ } | null>;
273
+ /** Get index with permissions (requires scope). */
274
+ getNetworkWithPermissions(networkId: string): Promise<{
275
+ id: string;
276
+ title: string;
277
+ permissions: {
278
+ joinPolicy: 'anyone' | 'invite_only';
279
+ };
280
+ } | null>;
281
+ /** Get member count for an index (requires scope). */
282
+ getNetworkMemberCount(networkId: string): Promise<number>;
283
+ /** Create an opportunity (cross-user). */
284
+ createOpportunity(data: CreateOpportunityData): Promise<Opportunity>;
285
+ /** Create opportunity and expire overlapping ones atomically. */
286
+ createOpportunityAndExpireIds(data: CreateOpportunityData, expireIds: string[]): Promise<{
287
+ created: Opportunity;
288
+ expired: Opportunity[];
289
+ }>;
290
+ /** Get an opportunity by ID (for system processing). */
291
+ getOpportunity(id: string): Promise<Opportunity | null>;
292
+ /** Get opportunities for an index (requires membership). */
293
+ getOpportunitiesForNetwork(networkId: string, options?: OpportunityQueryOptions): Promise<Opportunity[]>;
294
+ /** Update an opportunity's status (system-level). */
295
+ updateOpportunityStatus(id: string, status: OpportunityStatus, acceptedBy?: string): Promise<Opportunity | null>;
296
+ /** Stamp actor `actedAt` + update status atomically (system-level). */
297
+ stampOpportunityActorAction(id: string, actorUserId: string, status: OpportunityStatus, acceptedBy?: string): Promise<Opportunity | null>;
298
+ /** Check if opportunity exists between actors in an index. */
299
+ opportunityExistsBetweenActors(actorIds: string[], networkId: string): Promise<boolean>;
300
+ /** Find opportunities by actor IDs with optional include/exclude status filters. */
301
+ findOpportunitiesByActors(actorIds: string[], options?: {
302
+ includeIntroducers?: boolean;
303
+ statuses?: OpportunityStatus[];
304
+ excludeStatuses?: OpportunityStatus[];
305
+ }): Promise<Opportunity[]>;
306
+ /** Expire opportunities referencing an intent. */
307
+ expireOpportunitiesByIntent(intentId: string): Promise<number>;
308
+ /** Expire opportunities for a removed member. */
309
+ expireOpportunitiesForRemovedMember(networkId: string, userId: string): Promise<number>;
310
+ /** Expire stale opportunities (maintenance). */
311
+ expireStaleOpportunities(): Promise<number>;
312
+ /** Get a HyDE document (cross-user for matching). */
313
+ getHydeDocument(sourceType: HydeSourceType, sourceId: string, strategy: string): Promise<HydeDocument | null>;
314
+ /** Get all HyDE documents for a source (cross-user). */
315
+ getHydeDocumentsForSource(sourceType: HydeSourceType, sourceId: string): Promise<HydeDocument[]>;
316
+ /** Save a HyDE document (system-level). */
317
+ saveHydeDocument(data: CreateHydeDocumentData): Promise<HydeDocument>;
318
+ /** Delete expired HyDE documents (maintenance). */
319
+ deleteExpiredHydeDocuments(): Promise<number>;
320
+ /** Get stale HyDE documents for refresh (maintenance). */
321
+ getStaleHydeDocuments(threshold: Date): Promise<HydeDocument[]>;
322
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The database port itself, plus the two access-scoped views over it.
3
+ *
4
+ * `Database` is the union of the four query groups; splitting it into composed
5
+ * interfaces keeps each group readable without changing the type one bit —
6
+ * every `Pick<Database, ...>` alias still resolves exactly as before.
7
+ */
8
+ export {};
9
+ // ═══════════════════════════════════════════════════════════════════════════════
10
+ // NARROWED DATABASE INTERFACES (Interface Segregation)
11
+ // ═══════════════════════════════════════════════════════════════════════════════
12
+ //
13
+ // These narrowed types are Pick types from the raw Database interface.
14
+ // They are used by graph factories to enforce interface segregation at compile time.
15
+ //
16
+ // Access control relationship to UserDatabase/SystemDatabase:
17
+ // - EnrichmentGraphDatabase → maps to UserDatabase (user's own profile operations)
18
+ // - IntentGraphDatabase → maps to UserDatabase (mutations) + SystemDatabase (reads)
19
+ // - OpportunityGraphDatabase → maps to SystemDatabase (cross-user operations)
20
+ // - NetworkGraphDatabase → maps to UserDatabase (own indexes)
21
+ // - IntentNetworkGraphDatabase → maps to both (own intent ↔ shared network)
22
+ // - NetworkMembershipGraphDatabase → maps to SystemDatabase (cross-user)
23
+ // - HydeGraphDatabase → maps to both (own HyDE vs cross-user matching)
24
+ //
25
+ // Graphs continue to use these narrowed types because:
26
+ // 1. They receive the raw database adapter with userId passed per method
27
+ // 2. Access control is enforced at the tool/factory layer via createUserDatabase/createSystemDatabase
28
+ // 3. These types ensure graphs only depend on methods they actually use
29
+ // ═══════════════════════════════════════════════════════════════════════════════
@@ -131,17 +131,7 @@ export declare const DiscoveryNegotiationSchema: z.ZodObject<{
131
131
  }>;
132
132
  seedAssessmentScore: z.ZodOptional<z.ZodNumber>;
133
133
  }, "strip", z.ZodTypeAny, {
134
- counterpartyId: string;
135
- counterpartyHint: string;
136
134
  indexContext: string;
137
- turns: {
138
- reasoning: string;
139
- action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
140
- suggestedRoles: {
141
- ownUser: "agent" | "patient" | "peer";
142
- otherUser: "agent" | "patient" | "peer";
143
- };
144
- }[];
145
135
  outcome: {
146
136
  reasoning: string;
147
137
  hasOpportunity: boolean;
@@ -151,11 +141,8 @@ export declare const DiscoveryNegotiationSchema: z.ZodObject<{
151
141
  role: "agent" | "patient" | "peer";
152
142
  }[] | undefined;
153
143
  };
154
- seedAssessmentScore?: number | undefined;
155
- }, {
156
- counterpartyId: string;
157
144
  counterpartyHint: string;
158
- indexContext: string;
145
+ counterpartyId: string;
159
146
  turns: {
160
147
  reasoning: string;
161
148
  action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
@@ -164,6 +151,9 @@ export declare const DiscoveryNegotiationSchema: z.ZodObject<{
164
151
  otherUser: "agent" | "patient" | "peer";
165
152
  };
166
153
  }[];
154
+ seedAssessmentScore?: number | undefined;
155
+ }, {
156
+ indexContext: string;
167
157
  outcome: {
168
158
  reasoning: string;
169
159
  hasOpportunity: boolean;
@@ -173,6 +163,16 @@ export declare const DiscoveryNegotiationSchema: z.ZodObject<{
173
163
  role: "agent" | "patient" | "peer";
174
164
  }[] | undefined;
175
165
  };
166
+ counterpartyHint: string;
167
+ counterpartyId: string;
168
+ turns: {
169
+ reasoning: string;
170
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
171
+ suggestedRoles: {
172
+ ownUser: "agent" | "patient" | "peer";
173
+ otherUser: "agent" | "patient" | "peer";
174
+ };
175
+ }[];
176
176
  seedAssessmentScore?: number | undefined;
177
177
  }>;
178
178
  export type DiscoveryNegotiation = z.infer<typeof DiscoveryNegotiationSchema>;
@@ -39,8 +39,8 @@ export declare const DiscoveryNegotiationDigestSchema: z.ZodObject<{
39
39
  ownUser: "agent" | "patient" | "peer";
40
40
  otherUser: "agent" | "patient" | "peer";
41
41
  } | null;
42
- counterpartyHint: string;
43
42
  indexContext: string;
43
+ counterpartyHint: string;
44
44
  outcomeRole: "opportunity" | "no-opportunity";
45
45
  outcomeReason: "timeout" | "stalled" | "rejected" | "turn_cap" | "screened_out" | null;
46
46
  keyTake: string;
@@ -51,8 +51,8 @@ export declare const DiscoveryNegotiationDigestSchema: z.ZodObject<{
51
51
  } | null;
52
52
  outcomeRole: "opportunity" | "no-opportunity";
53
53
  outcomeReason: "timeout" | "stalled" | "rejected" | "turn_cap" | "screened_out" | null;
54
- counterpartyHint?: unknown;
55
54
  indexContext?: unknown;
55
+ counterpartyHint?: unknown;
56
56
  keyTake?: unknown;
57
57
  }>;
58
58
  export type DiscoveryNegotiationDigest = z.infer<typeof DiscoveryNegotiationDigestSchema>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indexnetwork/protocol",
3
- "version": "14.3.2-rc.477.1",
3
+ "version": "17.0.0-rc.479.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -28,20 +28,7 @@
28
28
  "architecture:capabilities": "bun scripts/architecture/capability-boundaries.ts",
29
29
  "architecture:check": "bun run architecture:host-isolation && bun run architecture:capabilities && bun run test:architecture",
30
30
  "prepublishOnly": "bun run build",
31
- "prepack": "bun run build:package",
32
- "eval:matching": "bun --env-file=../../.env.test ./eval/matching/matching.eval.ts",
33
- "eval:hyde": "bun --env-file=../../.env.test ./eval/hyde/hyde.eval.ts",
34
- "eval:premise": "bun --env-file=../../.env.test ./eval/premise/premise.eval.ts",
35
- "eval:profile": "bun --env-file=../../.env.test ./eval/profile/profile.eval.ts",
36
- "eval:opportunity": "bun --env-file=../../.env.test ./eval/opportunity/opportunity.eval.ts",
37
- "eval:clarification": "bun --env-file=../../.env.test ./eval/clarification/clarification.eval.ts",
38
- "eval:intake": "bun --env-file=../../.env.test ./eval/intake/intake.eval.ts",
39
- "eval:discovery-retrieval": "bun --env-file=../../.env.test ./eval/discovery-retrieval/discovery-retrieval.eval.ts",
40
- "eval:canary": "bun --env-file=../../.env.test ./eval/canary/canary.eval.ts",
41
- "eval:stance": "bun --env-file=../../.env.test ./eval/stance/stance.eval.ts",
42
- "eval:view": "bun ./eval/viewer/viewer.eval.ts",
43
- "eval:web": "bun --env-file=../../.env.test ./eval/ops/ops.serve.ts",
44
- "eval:verify": "bun ./eval/verify.ts"
31
+ "prepack": "bun run build:package"
45
32
  },
46
33
  "dependencies": {
47
34
  "@langchain/core": "1.1.48",
@@ -1,49 +0,0 @@
1
- /**
2
- * contacts/application — generateInviteMessage canonical implementation.
3
- *
4
- * Invite Generator Agent: generates contextual, editable invite messages for
5
- * ghost users. Produces warm, concise messages (~2-3 sentences) referencing
6
- * why two users were matched, with optional referrer mention.
7
- *
8
- * IND-549: moved from contact/contact.inviter.ts into the canonical
9
- * contacts/application layer.
10
- */
11
- import { z } from "zod";
12
- declare const InviteInputSchema: z.ZodObject<{
13
- recipientName: z.ZodString;
14
- senderName: z.ZodString;
15
- opportunityInterpretation: z.ZodString;
16
- senderIntents: z.ZodArray<z.ZodString, "many">;
17
- recipientIntents: z.ZodArray<z.ZodString, "many">;
18
- referrerName: z.ZodOptional<z.ZodString>;
19
- }, "strip", z.ZodTypeAny, {
20
- recipientName: string;
21
- senderName: string;
22
- opportunityInterpretation: string;
23
- senderIntents: string[];
24
- recipientIntents: string[];
25
- referrerName?: string | undefined;
26
- }, {
27
- recipientName: string;
28
- senderName: string;
29
- opportunityInterpretation: string;
30
- senderIntents: string[];
31
- recipientIntents: string[];
32
- referrerName?: string | undefined;
33
- }>;
34
- declare const InviteOutputSchema: z.ZodObject<{
35
- message: z.ZodString;
36
- }, "strip", z.ZodTypeAny, {
37
- message: string;
38
- }, {
39
- message: string;
40
- }>;
41
- export type InviteInput = z.infer<typeof InviteInputSchema>;
42
- export type InviteOutput = z.infer<typeof InviteOutputSchema>;
43
- /**
44
- * Generates a contextual invite message for a ghost user.
45
- * @param input - Context about sender, recipient, and opportunity
46
- * @returns Generated invite message text
47
- */
48
- export declare function generateInviteMessage(input: InviteInput): Promise<InviteOutput>;
49
- export {};
@@ -1,64 +0,0 @@
1
- /**
2
- * contacts/application — generateInviteMessage canonical implementation.
3
- *
4
- * Invite Generator Agent: generates contextual, editable invite messages for
5
- * ghost users. Produces warm, concise messages (~2-3 sentences) referencing
6
- * why two users were matched, with optional referrer mention.
7
- *
8
- * IND-549: moved from contact/contact.inviter.ts into the canonical
9
- * contacts/application layer.
10
- */
11
- import { HumanMessage, SystemMessage } from "@langchain/core/messages";
12
- import { z } from "zod";
13
- import { createStructuredModel } from "../../shared/agent/model.config.js";
14
- import { stripUnsupportedOpportunityClaims } from "../../shared/utils/claim-safety.js";
15
- const InviteInputSchema = z.object({
16
- recipientName: z.string(),
17
- senderName: z.string(),
18
- opportunityInterpretation: z.string(),
19
- senderIntents: z.array(z.string()),
20
- recipientIntents: z.array(z.string()),
21
- referrerName: z.string().optional(),
22
- });
23
- const InviteOutputSchema = z.object({
24
- message: z.string().describe("The invite message text, ready to edit and send"),
25
- });
26
- const SYSTEM_PROMPT = `You generate brief, casual invite messages for a discovery platform called Index.
27
-
28
- The sender wants to reach out to someone they were matched with. Write a short, human message (2-3 sentences max) that:
29
- - Sounds like a real person texting, not a LinkedIn outreach or AI email
30
- - References one concrete, specific detail from the opportunity context — something actual, like a specific project, technology, or goal they share. Not "we have similar interests" or "I noticed we're both in this space" — name the actual thing.
31
- - If a referrer is provided, casually drops that they were introduced
32
- - Ends naturally — no formal CTAs, no "Would you be open to..." closings
33
-
34
- Tone: casual, direct, human. Think how you'd actually message someone you just got introduced to.
35
- Do NOT use a generic opener like "Hi [Name], I'm [Sender]." Just get to the point.
36
- Do NOT summarize the person's background. Pick one real, specific overlap from the context and mention it.
37
- Do NOT include a subject line. This is a chat message.
38
- Do NOT use placeholder brackets like [Name]. Use the actual names provided.
39
- Network assignment, network title/type, and event/network metadata are retrieval context only. They are NEVER proof that either person attended or will attend, belongs to a group, resides in a place, knows anyone from the network, or shared a session, time, place, or location. Do not make co-attendance, membership, residence, shared-session, or same-place/same-time claims from network co-membership.`;
40
- /**
41
- * Generates a contextual invite message for a ghost user.
42
- * @param input - Context about sender, recipient, and opportunity
43
- * @returns Generated invite message text
44
- */
45
- export async function generateInviteMessage(input) {
46
- const validated = InviteInputSchema.parse(input);
47
- const structuredModel = createStructuredModel("inviteGenerator", InviteOutputSchema);
48
- const safeInterpretation = stripUnsupportedOpportunityClaims(validated.opportunityInterpretation) ||
49
- "Their current goals may be relevant to each other.";
50
- const userPrompt = `Generate an invite message with this context:
51
- - Sender: ${validated.senderName}
52
- - Recipient: ${validated.recipientName}
53
- - Why they matched: ${safeInterpretation}
54
- - Sender's interests: ${validated.senderIntents.join(', ') || 'Not specified'}
55
- - Recipient's interests: ${validated.recipientIntents.join(', ') || 'Not specified'}${validated.referrerName ? `\n- Referred by: ${validated.referrerName}` : ''}`;
56
- const result = InviteOutputSchema.parse(await structuredModel.invoke([
57
- new SystemMessage(SYSTEM_PROMPT),
58
- new HumanMessage(userPrompt),
59
- ]));
60
- const safeMessage = stripUnsupportedOpportunityClaims(result.message);
61
- return {
62
- message: safeMessage || "Thought it could be useful for us to compare notes on what we're working on.",
63
- };
64
- }
@@ -1,14 +0,0 @@
1
- /**
2
- * integrations/application — foreground adapters for the integrations capability.
3
- *
4
- * ## Exports
5
- *
6
- * ### Tool factory
7
- * - `createIntegrationTools` — creates integration MCP tools (import_gmail_contacts).
8
- * The tool is gated behind deps.contactsEnabled; when disabled, returns [].
9
- *
10
- * IND-549: canonical application layer for the integrations capability.
11
- * Legacy path:
12
- * - integration/integration.tools.ts → thin compatibility shim pointing here
13
- */
14
- export { createIntegrationTools } from "./integration.tools.js";
@@ -1,14 +0,0 @@
1
- /**
2
- * integrations/application — foreground adapters for the integrations capability.
3
- *
4
- * ## Exports
5
- *
6
- * ### Tool factory
7
- * - `createIntegrationTools` — creates integration MCP tools (import_gmail_contacts).
8
- * The tool is gated behind deps.contactsEnabled; when disabled, returns [].
9
- *
10
- * IND-549: canonical application layer for the integrations capability.
11
- * Legacy path:
12
- * - integration/integration.tools.ts → thin compatibility shim pointing here
13
- */
14
- export { createIntegrationTools } from "./integration.tools.js";
@@ -1,27 +0,0 @@
1
- /**
2
- * integrations/application — createIntegrationTools canonical implementation.
3
- *
4
- * Creates integration tools for the chat agent. Exposes `import_gmail_contacts`
5
- * which authenticates via the integration adapter, fetches all Gmail contacts
6
- * (paginated), and imports them as ghost users into the network.
7
- *
8
- * Feature gating: import_gmail_contacts creates ghost users, so it is gated
9
- * behind the CONTACTS_ENABLED flag (deps.contactsEnabled). When disabled,
10
- * the tool is not registered at all (defineTool registers as a side effect).
11
- *
12
- * IND-549: moved from integration/integration.tools.ts into the canonical
13
- * integrations/application layer.
14
- */
15
- import type { DefineTool } from '../../shared/agent/tool.helpers.js';
16
- import type { IntegrationToolDeps } from '../ports/index.js';
17
- /**
18
- * Creates integration tools for the chat agent.
19
- *
20
- * Exposes `import_gmail_contacts` which authenticates via the integration adapter,
21
- * fetches all Gmail contacts (paginated), and imports them as ghost users into the network.
22
- *
23
- * @param defineTool - Tool definition helper injected by the tool registry.
24
- * @param deps - Shared tool dependencies including the integration adapter.
25
- * @returns An array of tool definitions to register with the chat agent.
26
- */
27
- export declare function createIntegrationTools(defineTool: DefineTool, deps: IntegrationToolDeps): any[];