@indexnetwork/protocol 14.3.2-rc.477.1 → 16.1.1-rc.478.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 (140) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/IMPLEMENTATION.md +50 -52
  3. package/STABILITY.md +3 -3
  4. package/dist/chat/chat.agent.js +2 -2
  5. package/dist/chat/chat.graph.d.ts +41 -1
  6. package/dist/chat/chat.graph.js +108 -127
  7. package/dist/discovery/hyde.frame.d.ts +4 -4
  8. package/dist/discovery/hyde.graph.d.ts +71 -12
  9. package/dist/discovery/hyde.graph.js +337 -335
  10. package/dist/discovery/lens.inferrer.d.ts +6 -6
  11. package/dist/enrichment/enrichment.graph.d.ts +127 -9
  12. package/dist/enrichment/enrichment.graph.js +633 -655
  13. package/dist/enrichment/enrichment.state.d.ts +1 -1
  14. package/dist/enrichment/enrichment.tools.context-read.d.ts +10 -0
  15. package/dist/enrichment/enrichment.tools.context-read.js +353 -0
  16. package/dist/enrichment/enrichment.tools.context-write.d.ts +9 -0
  17. package/dist/enrichment/enrichment.tools.context-write.js +417 -0
  18. package/dist/enrichment/enrichment.tools.d.ts +11 -1
  19. package/dist/enrichment/enrichment.tools.helpers.d.ts +139 -0
  20. package/dist/enrichment/enrichment.tools.helpers.js +234 -0
  21. package/dist/enrichment/enrichment.tools.js +16 -975
  22. package/dist/index.d.ts +27 -48
  23. package/dist/index.js +17 -27
  24. package/dist/intents/application/intent.graph.d.ts +71 -67
  25. package/dist/intents/application/intent.graph.execute.d.ts +59 -0
  26. package/dist/intents/application/intent.graph.execute.js +301 -0
  27. package/dist/intents/application/intent.graph.infer.d.ts +44 -0
  28. package/dist/intents/application/intent.graph.infer.js +97 -0
  29. package/dist/intents/application/intent.graph.js +96 -888
  30. package/dist/intents/application/intent.graph.reconcile.d.ts +71 -0
  31. package/dist/intents/application/intent.graph.reconcile.js +274 -0
  32. package/dist/intents/application/intent.graph.shared.d.ts +70 -0
  33. package/dist/intents/application/intent.graph.shared.js +153 -0
  34. package/dist/intents/domain/intent.state.d.ts +1 -1
  35. package/dist/maintenance/maintenance.graph.d.ts +66 -3
  36. package/dist/maintenance/maintenance.graph.js +155 -156
  37. package/dist/mcp/mcp.authorization-policy.d.ts +24 -28
  38. package/dist/mcp/mcp.authorization-policy.js +14 -34
  39. package/dist/mcp/mcp.server.d.ts +3 -3
  40. package/dist/mcp/mcp.server.js +12 -16
  41. package/dist/negotiations/application/negotiation.candidates.d.ts +83 -0
  42. package/dist/negotiations/application/negotiation.candidates.js +162 -0
  43. package/dist/negotiations/application/negotiation.graph.d.ts +91 -157
  44. package/dist/negotiations/application/negotiation.graph.finalize.d.ts +5 -0
  45. package/dist/negotiations/application/negotiation.graph.finalize.js +280 -0
  46. package/dist/negotiations/application/negotiation.graph.init.d.ts +54 -0
  47. package/dist/negotiations/application/negotiation.graph.init.js +227 -0
  48. package/dist/negotiations/application/negotiation.graph.js +69 -1388
  49. package/dist/negotiations/application/negotiation.graph.screen.d.ts +23 -0
  50. package/dist/negotiations/application/negotiation.graph.screen.js +108 -0
  51. package/dist/negotiations/application/negotiation.graph.shared.d.ts +75 -0
  52. package/dist/negotiations/application/negotiation.graph.shared.js +125 -0
  53. package/dist/negotiations/application/negotiation.graph.turn.d.ts +105 -0
  54. package/dist/negotiations/application/negotiation.graph.turn.js +484 -0
  55. package/dist/negotiations/domain/negotiation.state.d.ts +1 -1
  56. package/dist/negotiations/domain/negotiation.state.js +0 -1
  57. package/dist/networks/application/indexer.graph.d.ts +165 -7
  58. package/dist/networks/application/indexer.graph.js +339 -388
  59. package/dist/networks/application/indexer.state.d.ts +1 -1
  60. package/dist/networks/application/membership.graph.d.ts +83 -5
  61. package/dist/networks/application/membership.graph.js +177 -207
  62. package/dist/networks/application/network.graph.d.ts +148 -5
  63. package/dist/networks/application/network.graph.js +249 -278
  64. package/dist/networks/domain/membership.state.d.ts +1 -1
  65. package/dist/networks/domain/network.state.d.ts +1 -1
  66. package/dist/opportunities/application/delivery-card.cache.d.ts +1 -1
  67. package/dist/opportunities/application/delivery-card.cache.js +2 -2
  68. package/dist/opportunities/application/index.d.ts +2 -2
  69. package/dist/opportunities/application/index.js +2 -2
  70. package/dist/opportunities/application/opportunity.evaluator.js +1 -1
  71. package/dist/opportunities/application/opportunity.graph.d.ts +686 -473
  72. package/dist/opportunities/application/opportunity.graph.discovery-strategies.d.ts +109 -0
  73. package/dist/opportunities/application/opportunity.graph.discovery-strategies.js +451 -0
  74. package/dist/opportunities/application/opportunity.graph.discovery.d.ts +69 -0
  75. package/dist/opportunities/application/opportunity.graph.discovery.js +397 -0
  76. package/dist/opportunities/application/opportunity.graph.evaluation.d.ts +82 -0
  77. package/dist/opportunities/application/opportunity.graph.evaluation.js +608 -0
  78. package/dist/opportunities/application/opportunity.graph.js +120 -3690
  79. package/dist/opportunities/application/opportunity.graph.modes.d.ts +538 -0
  80. package/dist/opportunities/application/opportunity.graph.modes.js +538 -0
  81. package/dist/opportunities/application/opportunity.graph.negotiate.d.ts +109 -0
  82. package/dist/opportunities/application/opportunity.graph.negotiate.js +392 -0
  83. package/dist/opportunities/application/opportunity.graph.persist-node.d.ts +93 -0
  84. package/dist/opportunities/application/opportunity.graph.persist-node.js +765 -0
  85. package/dist/opportunities/application/opportunity.graph.prep.d.ts +150 -0
  86. package/dist/opportunities/application/opportunity.graph.prep.js +381 -0
  87. package/dist/opportunities/application/opportunity.graph.shared.d.ts +173 -0
  88. package/dist/opportunities/application/opportunity.graph.shared.js +199 -0
  89. package/dist/opportunities/application/opportunity.presentation.d.ts +399 -0
  90. package/dist/opportunities/application/{opportunity.presenter.js → opportunity.presentation.js} +735 -9
  91. package/dist/opportunities/application/opportunity.tools.cards.d.ts +152 -0
  92. package/dist/opportunities/application/opportunity.tools.cards.js +235 -0
  93. package/dist/opportunities/application/opportunity.tools.d.ts +8 -114
  94. package/dist/opportunities/application/opportunity.tools.js +28 -711
  95. package/dist/opportunities/application/opportunity.tools.list.d.ts +10 -0
  96. package/dist/opportunities/application/opportunity.tools.list.js +493 -0
  97. package/dist/opportunities/domain/index.d.ts +3 -3
  98. package/dist/opportunities/domain/index.js +3 -3
  99. package/dist/opportunities/domain/opportunity.state.d.ts +19 -19
  100. package/dist/opportunities/index.d.ts +6 -6
  101. package/dist/opportunities/index.js +4 -4
  102. package/dist/opportunities/ports/opportunity.tools.port.d.ts +1 -1
  103. package/dist/opportunities/radar/radar.graph.d.ts +57 -13
  104. package/dist/opportunities/radar/radar.graph.js +470 -471
  105. package/dist/premises/premise.graph.d.ts +88 -20
  106. package/dist/premises/premise.graph.js +207 -218
  107. package/dist/questions/domain/question.schema.d.ts +40 -40
  108. package/dist/shared/agent/tool.helpers.d.ts +21 -0
  109. package/dist/shared/agent/tool.registry.d.ts +4 -3
  110. package/dist/shared/agent/tool.registry.js +1 -1
  111. package/dist/shared/interfaces/database.capabilities.d.ts +100 -0
  112. package/dist/shared/interfaces/database.capabilities.js +7 -0
  113. package/dist/shared/interfaces/database.entities.d.ts +533 -0
  114. package/dist/shared/interfaces/database.entities.js +10 -0
  115. package/dist/shared/interfaces/database.identity-queries.d.ts +294 -0
  116. package/dist/shared/interfaces/database.identity-queries.js +4 -0
  117. package/dist/shared/interfaces/database.interface.d.ts +15 -2277
  118. package/dist/shared/interfaces/database.interface.js +8 -0
  119. package/dist/shared/interfaces/database.member-queries.d.ts +228 -0
  120. package/dist/shared/interfaces/database.member-queries.js +4 -0
  121. package/dist/shared/interfaces/database.negotiation.d.ts +305 -0
  122. package/dist/shared/interfaces/database.negotiation.js +26 -0
  123. package/dist/shared/interfaces/database.network-queries.d.ts +277 -0
  124. package/dist/shared/interfaces/database.network-queries.js +4 -0
  125. package/dist/shared/interfaces/database.opportunity-queries.d.ts +285 -0
  126. package/dist/shared/interfaces/database.opportunity-queries.js +4 -0
  127. package/dist/shared/interfaces/database.port.d.ts +322 -0
  128. package/dist/shared/interfaces/database.port.js +29 -0
  129. package/dist/shared/schemas/discovery-question.schema.d.ts +14 -14
  130. package/dist/shared/schemas/negotiation-digest.schema.d.ts +2 -2
  131. package/package.json +2 -15
  132. package/dist/opportunities/application/opportunity.card-presentation.d.ts +0 -44
  133. package/dist/opportunities/application/opportunity.card-presentation.js +0 -93
  134. package/dist/opportunities/application/opportunity.presenter.d.ts +0 -156
  135. package/dist/opportunities/domain/opportunity.presentation-cache.d.ts +0 -5
  136. package/dist/opportunities/domain/opportunity.presentation-cache.js +0 -11
  137. package/dist/opportunities/domain/opportunity.presentation.d.ts +0 -76
  138. package/dist/opportunities/domain/opportunity.presentation.js +0 -516
  139. package/dist/opportunities/domain/opportunity.safe-presentation.d.ts +0 -104
  140. package/dist/opportunities/domain/opportunity.safe-presentation.js +0 -102
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Helpers shared by the enrichment tools.
3
+ *
4
+ * These were nested functions inside `createEnrichmentTools`, closing over the
5
+ * destructured host capabilities. They are top-level now, each taking the tool
6
+ * deps explicitly, so the three tool modules can share them.
7
+ */
8
+ import { z } from "zod";
9
+ import { requestContext } from "../shared/observability/request-context.js";
10
+ import { protocolLogger } from "../shared/observability/protocol.logger.js";
11
+ import { socialsToEnrichmentRequest } from "../shared/utils/social-label.js";
12
+ import { normalizeTelegramHandle } from "../shared/utils/telegram-handle.js";
13
+ import { focusedNetworkId } from "../shared/agent/tool.scope.js";
14
+ export const logger = protocolLogger("ChatTools:Enrichment");
15
+ export function isMeaningfulEnrichment(enrichment) {
16
+ return !!enrichment &&
17
+ enrichment.confidentMatch &&
18
+ (enrichment.identity.bio.trim().length > 0 ||
19
+ enrichment.narrative.context.trim().length > 0 ||
20
+ enrichment.attributes.skills.length > 0 ||
21
+ enrichment.attributes.interests.length > 0);
22
+ }
23
+ export const approvedProfileDraftSchema = z.object({
24
+ identity: z.object({ name: z.string(), bio: z.string(), location: z.string() }),
25
+ narrative: z.object({ context: z.string() }),
26
+ attributes: z.object({ interests: z.array(z.string()), skills: z.array(z.string()) }),
27
+ });
28
+ export function trimToUndefined(value) {
29
+ const trimmed = value?.trim();
30
+ return trimmed && trimmed.length > 0 ? trimmed : undefined;
31
+ }
32
+ export function isPlaceholderName(value) {
33
+ const normalized = value.trim().toLowerCase();
34
+ return normalized === 'unknown' || normalized === 'user';
35
+ }
36
+ export async function enrichFromUserRecord(deps, user) {
37
+ const enrichmentSocials = socialsToEnrichmentRequest(user.socials);
38
+ return deps.enricher.enrichUserProfile({
39
+ name: trimToUndefined(user.name),
40
+ email: trimToUndefined(user.email),
41
+ linkedin: enrichmentSocials.linkedin || undefined,
42
+ twitter: enrichmentSocials.twitter || undefined,
43
+ github: enrichmentSocials.github || undefined,
44
+ telegram: enrichmentSocials.telegram || undefined,
45
+ websites: enrichmentSocials.websites?.length ? enrichmentSocials.websites : undefined,
46
+ });
47
+ }
48
+ export function selectProfileSeed(onboarding, networkId) {
49
+ const seeds = onboarding?.profileSeeds ?? [];
50
+ if (seeds.length === 0)
51
+ return undefined;
52
+ const scoped = networkId ? seeds.filter((seed) => seed.networkId === networkId) : seeds;
53
+ return scoped[scoped.length - 1];
54
+ }
55
+ export function normalizeSocialUpdate(label, value) {
56
+ const normalizedLabel = label.trim().toLowerCase();
57
+ if (!normalizedLabel)
58
+ return null;
59
+ const trimmedValue = value.trim();
60
+ if (!trimmedValue)
61
+ return null;
62
+ if (normalizedLabel === 'telegram') {
63
+ const handle = normalizeTelegramHandle(trimmedValue);
64
+ return handle ? { label: normalizedLabel, value: handle } : null;
65
+ }
66
+ return { label: normalizedLabel, value: trimmedValue };
67
+ }
68
+ export async function mergeUserSocials(deps, incoming) {
69
+ const normalizedIncoming = incoming
70
+ .map((social) => normalizeSocialUpdate(social.label, social.value))
71
+ .filter((social) => social !== null);
72
+ if (normalizedIncoming.length === 0)
73
+ return;
74
+ const existingSocials = await deps.userDb.getUserSocials();
75
+ const incomingLabels = new Set(normalizedIncoming.map((social) => social.label));
76
+ const kept = existingSocials
77
+ .filter((social) => !incomingLabels.has(social.label) || social.label === 'custom')
78
+ .map((social) => ({ label: social.label, value: social.value }));
79
+ const merged = incomingLabels.has('custom')
80
+ ? [...kept.filter((social) => social.label !== 'custom'), ...normalizedIncoming]
81
+ : [...kept, ...normalizedIncoming];
82
+ await deps.userDb.setUserSocials(merged);
83
+ }
84
+ export function socialsRecordToRows(socials) {
85
+ if (!socials)
86
+ return [];
87
+ return Object.entries(socials).map(([label, value]) => ({ label, value }));
88
+ }
89
+ export async function enqueueEnrichmentRun(deps, context, operation, input) {
90
+ if (!context.isMcp || !deps.enrichmentRuns || !deps.enrichmentRunQueue)
91
+ return null;
92
+ const run = await deps.enrichmentRuns.create({
93
+ userId: context.userId,
94
+ agentId: context.agentId ?? null,
95
+ operation,
96
+ input,
97
+ context: {
98
+ userId: context.userId,
99
+ userName: context.userName,
100
+ userEmail: context.userEmail,
101
+ ...(focusedNetworkId(context) ? { scopeType: 'network', scopeId: focusedNetworkId(context) } : {}),
102
+ ...(context.indexName ? { indexName: context.indexName } : {}),
103
+ ...(context.sessionId ? { sessionId: context.sessionId } : {}),
104
+ ...(context.agentId ? { agentId: context.agentId } : {}),
105
+ },
106
+ });
107
+ try {
108
+ await deps.enrichmentRunQueue.enqueue(run.id);
109
+ }
110
+ catch (err) {
111
+ const message = err instanceof Error ? err.message : String(err);
112
+ await deps.enrichmentRuns.markFailed(run.id, message);
113
+ if (err instanceof Error)
114
+ throw err;
115
+ const wrapped = new Error(`Failed to enqueue profile run: ${message}`);
116
+ wrapped.cause = err;
117
+ throw wrapped;
118
+ }
119
+ return run.id;
120
+ }
121
+ export async function persistApprovedProfileContext(deps, profile, user, networkId) {
122
+ await deps.userDb.updateUser({
123
+ name: profile.identity.name,
124
+ intro: profile.identity.bio,
125
+ location: profile.identity.location,
126
+ });
127
+ const onboarding = user?.onboarding ?? undefined;
128
+ const seed = selectProfileSeed(onboarding, networkId);
129
+ if (!seed?.socials?.length)
130
+ return;
131
+ await mergeUserSocials(deps, seed.socials);
132
+ }
133
+ export async function markApprovedProfileConfirmed(deps, context) {
134
+ const latestUser = await deps.userDb.getUser();
135
+ const currentOnboarding = latestUser?.onboarding ?? context.user.onboarding ?? {};
136
+ await deps.userDb.updateUser({
137
+ onboarding: {
138
+ ...currentOnboarding,
139
+ profileConfirmedAt: currentOnboarding.profileConfirmedAt ?? new Date().toISOString(),
140
+ currentStep: currentOnboarding.completedAt
141
+ ? currentOnboarding.currentStep ?? 'complete'
142
+ : 'first_signal',
143
+ },
144
+ });
145
+ }
146
+ export function buildProfileInput(parts) {
147
+ const lines = [];
148
+ if (parts.name)
149
+ lines.push(`Name: ${parts.name}`);
150
+ if (parts.location)
151
+ lines.push(`Location: ${parts.location}`);
152
+ if (parts.bioOrDescription)
153
+ lines.push(parts.bioOrDescription);
154
+ if (parts.socials?.length) {
155
+ lines.push(`User-provided public links:\n${parts.socials.map((s) => `${s.label}: ${s.value}`).join('\n')}`);
156
+ }
157
+ return lines.filter((line) => line.trim().length > 0).join('\n\n');
158
+ }
159
+ export function toProfileSummary(profile) {
160
+ return {
161
+ name: profile.identity.name,
162
+ bio: profile.identity.bio,
163
+ location: profile.identity.location,
164
+ skills: profile.attributes.skills,
165
+ interests: profile.attributes.interests,
166
+ };
167
+ }
168
+ export function buildApprovedDraftProfileInput(draft) {
169
+ return [
170
+ draft.identity.name ? `My name is ${draft.identity.name}.` : '',
171
+ draft.identity.location ? `I am based in ${draft.identity.location}.` : '',
172
+ draft.identity.bio || '',
173
+ draft.narrative.context || '',
174
+ draft.attributes.skills.length ? `My skills include ${draft.attributes.skills.join(', ')}.` : '',
175
+ draft.attributes.interests.length ? `My interests include ${draft.attributes.interests.join(', ')}.` : '',
176
+ ].filter((part) => part.trim().length > 0).join('\n');
177
+ }
178
+ export async function decomposeApprovedDraftProfile(deps, profile) {
179
+ const input = buildApprovedDraftProfileInput(profile);
180
+ if (!input.trim())
181
+ return;
182
+ const traceEmitter = requestContext.getStore()?.traceEmitter;
183
+ const graphStart = Date.now();
184
+ traceEmitter?.({ type: "graph_start", name: "enrichment" });
185
+ try {
186
+ const graphInput = {
187
+ userId: profile.userId,
188
+ operationMode: 'write',
189
+ input,
190
+ forceUpdate: true,
191
+ };
192
+ // Always invoked as a background fire-and-forget task (see confirm_user_context
193
+ // call sites), so decomposition must outlive the originating request — invoke
194
+ // the graph directly and never bind the request abort signal, which would
195
+ // cancel it as soon as the web request completes.
196
+ const result = await deps.graphs.profile.invoke(graphInput);
197
+ if (result.error) {
198
+ const err = new Error(result.error);
199
+ logger.error('Approved draft premise decomposition failed', {
200
+ userId: profile.userId,
201
+ error: result.error,
202
+ });
203
+ deps.reportToolError?.(err, {
204
+ subsystem: 'enrichment',
205
+ operation: 'profile.confirm_draft_decompose',
206
+ toolName: 'confirm_user_context',
207
+ userId: profile.userId,
208
+ tags: { toolName: 'confirm_user_context', execution: 'background' },
209
+ });
210
+ return;
211
+ }
212
+ // The write graph's decompose → aggregate → generate → save_profile
213
+ // pipeline persists the aggregate profile. The approved draft was already
214
+ // saved before decomposition started, so the DB is consistent regardless
215
+ // of graph outcome. Do not re-save here — the graph's save_profile is
216
+ // authoritative, and a concurrent user-driven profile update could race.
217
+ }
218
+ catch (err) {
219
+ logger.error('Approved draft premise decomposition failed', {
220
+ userId: profile.userId,
221
+ error: err instanceof Error ? err.message : String(err),
222
+ });
223
+ deps.reportToolError?.(err, {
224
+ subsystem: 'enrichment',
225
+ operation: 'profile.confirm_draft_decompose',
226
+ toolName: 'confirm_user_context',
227
+ userId: profile.userId,
228
+ tags: { toolName: 'confirm_user_context', execution: 'background' },
229
+ });
230
+ }
231
+ finally {
232
+ traceEmitter?.({ type: "graph_end", name: "enrichment", durationMs: Date.now() - graphStart });
233
+ }
234
+ }