@lucern/sdk 1.0.29 → 1.0.31

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 (191) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/accessControl.d.ts +31 -31
  3. package/dist/accessControl.js +1 -0
  4. package/dist/adminClient.d.ts +74 -74
  5. package/dist/adminClient.js +38 -30
  6. package/dist/{answersClient.d.ts → answers-client.d.ts} +1 -1
  7. package/dist/{answersClient.js → answers-client.js} +2 -2
  8. package/dist/audience/index.d.ts +12 -12
  9. package/dist/{audiencesClient.d.ts → audiences-client.d.ts} +1 -1
  10. package/dist/audiences-client.js +107 -0
  11. package/dist/{auditClient.d.ts → audit-client.d.ts} +2 -3
  12. package/dist/{auditClient.js → audit-client.js} +8 -7
  13. package/dist/authContext.d.ts +26 -26
  14. package/dist/authDeviceClient.d.ts +11 -11
  15. package/dist/authDeviceClient.js +4 -6
  16. package/dist/beliefs/index.d.ts +56 -28
  17. package/dist/beliefs/index.js +2 -1
  18. package/dist/beliefsClient.d.ts +71 -63
  19. package/dist/beliefsClient.js +90 -67
  20. package/dist/{boundaryClientSurface.d.ts → boundary-client-surface.d.ts} +4 -4
  21. package/dist/{boundaryClientSurface.js → boundary-client-surface.js} +9 -7
  22. package/dist/client-assembly-types.d.ts +219 -0
  23. package/dist/client-assembly-types.js +2 -0
  24. package/dist/{clientConfig.d.ts → client-config.d.ts} +16 -32
  25. package/dist/client-config.js +2 -0
  26. package/dist/{clientEvidenceCompat.d.ts → client-evidence-compat.d.ts} +24 -24
  27. package/dist/{clientEvidenceCompat.js → client-evidence-compat.js} +2 -2
  28. package/dist/client.d.ts +1906 -352
  29. package/dist/client.js +34 -30
  30. package/dist/clientGraphNamespaces.d.ts +35 -25
  31. package/dist/clientGraphNamespaces.js +11 -5
  32. package/dist/clientHelpers.js +8 -5
  33. package/dist/clientKnowledgeNamespaces.d.ts +124 -84
  34. package/dist/clientKnowledgeNamespaces.js +35 -34
  35. package/dist/clientLocalHelpers.d.ts +81 -52
  36. package/dist/clientLocalHelpers.js +193 -43
  37. package/dist/clientPlatformNamespaces.d.ts +1541 -150
  38. package/dist/clientPlatformNamespaces.js +10 -5
  39. package/dist/clientRuntime.d.ts +1 -1
  40. package/dist/clientRuntime.js +1 -1
  41. package/dist/clientWorkflowNamespaces.d.ts +211 -97
  42. package/dist/clientWorkflowNamespaces.js +22 -19
  43. package/dist/contextClient.d.ts +2 -2
  44. package/dist/contextClient.js +79 -50
  45. package/dist/contextFacade.d.ts +1 -1
  46. package/dist/contextFacade.js +2 -0
  47. package/dist/contextPackCompiler.d.ts +52 -52
  48. package/dist/contextPackCompiler.js +192 -122
  49. package/dist/contextPackPolicy.d.ts +22 -22
  50. package/dist/contextPackPolicy.js +21 -9
  51. package/dist/contextPackSchema.d.ts +3 -3
  52. package/dist/contextPackSchema.js +1 -0
  53. package/dist/contextTypes.d.ts +155 -155
  54. package/dist/contracts/api-enums.contract.js +2 -11
  55. package/dist/contracts/auth-session.contract.d.ts +16 -16
  56. package/dist/contracts/auth-session.contract.js +3 -2
  57. package/dist/contracts/context-pack.contract.d.ts +216 -216
  58. package/dist/contracts/contextPack.js +2 -0
  59. package/dist/contracts/index.d.ts +1 -1
  60. package/dist/contracts/index.js +2 -1
  61. package/dist/contracts/lens-filter.contract.d.ts +8 -8
  62. package/dist/contracts/lens-filter.contract.js +10 -10
  63. package/dist/contracts/lens-workflow.contract.d.ts +32 -32
  64. package/dist/contracts/lens-workflow.contract.js +2 -1
  65. package/dist/contracts/lensFilter.js +2 -0
  66. package/dist/contracts/lensWorkflow.js +2 -0
  67. package/dist/contracts/mcpTools.d.ts +19 -19
  68. package/dist/contracts/mcpTools.js +3 -1
  69. package/dist/contracts/prompt.contract.d.ts +12 -12
  70. package/dist/contracts/prompt.js +1 -0
  71. package/dist/contracts/sdk-tools.contract.js +1 -0
  72. package/dist/contracts/sdkTools.js +2 -0
  73. package/dist/contracts/tool-contracts.js +1 -0
  74. package/dist/contracts/workflow-runtime.contract.d.ts +45 -45
  75. package/dist/contracts/workflow-runtime.contract.js +1 -5
  76. package/dist/contracts/workflowRuntime.js +2 -0
  77. package/dist/contradictions/index.d.ts +8 -8
  78. package/dist/contradictions/index.js +1 -0
  79. package/dist/control-plane.d.ts +10 -10
  80. package/dist/control-plane.js +2 -2
  81. package/dist/controlObjectOwnership.d.ts +11 -11
  82. package/dist/controlObjectOwnership.js +1 -0
  83. package/dist/coreClient.d.ts +51 -51
  84. package/dist/coreClient.js +269 -101
  85. package/dist/customTools.d.ts +19 -19
  86. package/dist/customTools.js +4 -2
  87. package/dist/decisions/index.d.ts +18 -18
  88. package/dist/decisions/index.js +1 -0
  89. package/dist/decisionsClient.d.ts +4 -4
  90. package/dist/decisionsClient.js +36 -27
  91. package/dist/edges/index.d.ts +20 -18
  92. package/dist/edges/index.js +1 -0
  93. package/dist/embeddingsClient.d.ts +29 -29
  94. package/dist/embeddingsClient.js +15 -8
  95. package/dist/eventingClient.d.ts +27 -27
  96. package/dist/eventingClient.js +10 -5
  97. package/dist/events.d.ts +83 -83
  98. package/dist/events.js +19 -15
  99. package/dist/eventsCore.d.ts +7 -7
  100. package/dist/eventsCore.js +11 -10
  101. package/dist/evidence/index.d.ts +23 -21
  102. package/dist/evidence/index.js +1 -0
  103. package/dist/evidenceClient.d.ts +23 -23
  104. package/dist/evidenceClient.js +10 -6
  105. package/dist/facade/context.d.ts +9 -9
  106. package/dist/facade/context.js +67 -41
  107. package/dist/functionSurface.js +2 -0
  108. package/dist/functionSurfaceClient.js +2 -0
  109. package/dist/gatewayFacades.d.ts +215 -215
  110. package/dist/gatewayFacades.factories.d.ts +23 -44
  111. package/dist/gatewayFacades.factories.js +63 -62
  112. package/dist/gatewayFacades.js +31 -32
  113. package/dist/graphAnalysisClient.d.ts +60 -60
  114. package/dist/graphAnalysisClient.js +19 -18
  115. package/dist/graphClient.d.ts +34 -34
  116. package/dist/graphClient.js +56 -35
  117. package/dist/graphIntel.js +2 -0
  118. package/dist/graphIntelligence.d.ts +2 -2
  119. package/dist/graphIntelligence.js +1 -1
  120. package/dist/graphRecommendationsClient.d.ts +24 -24
  121. package/dist/graphRecommendationsClient.js +12 -7
  122. package/dist/graphStateClassifierClient.d.ts +13 -13
  123. package/dist/graphStateClassifierClient.js +10 -5
  124. package/dist/harnessClient.d.ts +61 -61
  125. package/dist/harnessClient.js +44 -31
  126. package/dist/identityClient.d.ts +33 -59
  127. package/dist/identityClient.js +126 -98
  128. package/dist/index.d.ts +20 -20
  129. package/dist/index.js +20 -19
  130. package/dist/infisicalRuntime.d.ts +11 -11
  131. package/dist/infisicalRuntime.js +20 -14
  132. package/dist/jobsClient.d.ts +28 -28
  133. package/dist/jobsClient.js +6 -3
  134. package/dist/learningClient.js +13 -8
  135. package/dist/lenses/index.d.ts +124 -28
  136. package/dist/lenses/index.js +1 -0
  137. package/dist/mcpClient.d.ts +1 -1
  138. package/dist/mcpClient.js +3 -3
  139. package/dist/modelRuntimeClient.d.ts +27 -27
  140. package/dist/modelRuntimeClient.js +10 -5
  141. package/dist/nodes/index.d.ts +9 -9
  142. package/dist/nodes/index.js +1 -0
  143. package/dist/ontologies/index.d.ts +68 -22
  144. package/dist/ontologies/index.js +1 -0
  145. package/dist/ontologyClient.js +24 -17
  146. package/dist/ontologyLinksClient.d.ts +35 -35
  147. package/dist/ontologyLinksClient.js +9 -6
  148. package/dist/opinion.d.ts +3 -3
  149. package/dist/opinion.js +12 -5
  150. package/dist/orgGraphSearchClient.d.ts +39 -39
  151. package/dist/orgGraphSearchClient.js +22 -13
  152. package/dist/packsClient.d.ts +1 -1
  153. package/dist/packsClient.js +28 -19
  154. package/dist/policyClient.d.ts +79 -68
  155. package/dist/policyClient.js +18 -12
  156. package/dist/proof-attestation.json +1 -1
  157. package/dist/questions/index.d.ts +38 -27
  158. package/dist/questions/index.js +1 -0
  159. package/dist/realtime/index.d.ts +3 -3
  160. package/dist/realtime/index.js +1 -0
  161. package/dist/realtime/refs.d.ts +2 -2
  162. package/dist/{reportsClient.d.ts → reports-client.d.ts} +2 -2
  163. package/dist/{reportsClient.js → reports-client.js} +19 -13
  164. package/dist/{schemaClient.d.ts → schema-client.d.ts} +2 -3
  165. package/dist/{schemaClient.js → schema-client.js} +14 -11
  166. package/dist/sdkSurface.d.ts +12 -12
  167. package/dist/sdkSurface.js +14 -10
  168. package/dist/secrets.d.ts +1 -1
  169. package/dist/secrets.js +2 -1
  170. package/dist/{sourcesClient.d.ts → sources-client.d.ts} +8 -9
  171. package/dist/{sourcesClient.js → sources-client.js} +4 -5
  172. package/dist/{telemetryClient.d.ts → telemetry-client.d.ts} +14 -14
  173. package/dist/{telemetryClient.js → telemetry-client.js} +6 -4
  174. package/dist/toolRegistryClient.d.ts +46 -46
  175. package/dist/toolRegistryClient.js +22 -11
  176. package/dist/topics/index.d.ts +23 -23
  177. package/dist/topics/index.js +2 -1
  178. package/dist/topicsClient.d.ts +6 -6
  179. package/dist/topicsClient.js +29 -18
  180. package/dist/types.d.ts +356 -355
  181. package/dist/version.d.ts +1 -1
  182. package/dist/version.js +1 -1
  183. package/dist/workflowClient.d.ts +36 -35
  184. package/dist/workflowClient.js +88 -60
  185. package/dist/worktrees/index.d.ts +118 -32
  186. package/dist/worktrees/index.js +2 -1
  187. package/package.json +45 -5
  188. package/dist/audiencesClient.js +0 -115
  189. package/dist/clientAssemblyTypes.d.ts +0 -33
  190. package/dist/clientAssemblyTypes.js +0 -2
  191. package/dist/clientConfig.js +0 -2
@@ -1,6 +1,8 @@
1
- import { CONTEXT_PACK_SCHEMA_VERSION, DEFAULT_COMPILATION_MODE, DEFAULT_ENTITY_LIMIT, MAX_ENTITY_LIMIT, } from "./contracts/context-pack.contract.js";
1
+ // biome-ignore-all lint/style/useFilenamingConvention: This file is an @lucern/sdk public import ABI / package subpath compatibility surface; the camelCase filename is intentional.
2
2
  import { buildInjectionPlan, parseTokenBudget, rankContextSection, rankEntities, resolveEffectiveWeights, } from "./contextPackPolicy.js";
3
3
  import { validateContextPackSchema } from "./contextPackSchema.js";
4
+ import { CONTEXT_PACK_SCHEMA_VERSION, DEFAULT_COMPILATION_MODE, DEFAULT_ENTITY_LIMIT, MAX_ENTITY_LIMIT, } from "./contracts/context-pack.contract.js";
5
+ const QUERY_TOKEN_SPLIT_PATTERN = /[^a-z0-9]+/;
4
6
  function assertContextPackSchema(payload) {
5
7
  const result = validateContextPackSchema(payload);
6
8
  if (!result.valid) {
@@ -28,7 +30,7 @@ function normalizeQueryTokens(query) {
28
30
  }
29
31
  return query
30
32
  .toLowerCase()
31
- .split(/[^a-z0-9]+/)
33
+ .split(QUERY_TOKEN_SPLIT_PATTERN)
32
34
  .map((token) => token.trim())
33
35
  .filter((token) => token.length >= 2);
34
36
  }
@@ -129,7 +131,11 @@ function candidateTimestamp(candidate) {
129
131
  if (!isRecord(candidate)) {
130
132
  return 0;
131
133
  }
132
- const timestamps = [candidate.updatedAt, candidate.createdAt, candidate.generatedAt].filter((value) => typeof value === "number" && Number.isFinite(value));
134
+ const timestamps = [
135
+ candidate.updatedAt,
136
+ candidate.createdAt,
137
+ candidate.generatedAt,
138
+ ].filter((value) => typeof value === "number" && Number.isFinite(value));
133
139
  return timestamps.length > 0 ? Math.max(...timestamps) : 0;
134
140
  }
135
141
  function resolveReferenceTimeMs(...collections) {
@@ -144,45 +150,73 @@ function resolveReferenceTimeMs(...collections) {
144
150
  }
145
151
  return maxTimestamp;
146
152
  }
153
+ function contradictionSeverity(weight) {
154
+ if (weight <= -0.9) {
155
+ return "critical";
156
+ }
157
+ if (weight <= -0.7) {
158
+ return "high";
159
+ }
160
+ if (weight <= -0.5) {
161
+ return "medium";
162
+ }
163
+ return "low";
164
+ }
165
+ function optionalArgString(args, key) {
166
+ const value = args[key];
167
+ return typeof value === "string" && value.trim().length > 0
168
+ ? value.trim()
169
+ : undefined;
170
+ }
171
+ function rankingProfileFromArgs(args) {
172
+ return parseRankingProfile(typeof args.ranking === "string" ? args.ranking : args.rankingProfile);
173
+ }
174
+ function tokenBudgetFromArgs(args) {
175
+ return parseTokenBudget(typeof args.budget === "number" ? args.budget : args.tokenBudget, 1800);
176
+ }
177
+ function descendantDepthFromArgs(args, topic) {
178
+ const topicDepth = typeof topic.depth === "number" && Number.isFinite(topic.depth)
179
+ ? topic.depth
180
+ : 0;
181
+ if (typeof args.maxDepth === "number" && Number.isFinite(args.maxDepth)) {
182
+ return Math.max(1, Math.min(Math.floor(args.maxDepth), 6));
183
+ }
184
+ return topicDepth <= 1 ? 4 : 2;
185
+ }
186
+ function packWeightOverridesFromArgs(args) {
187
+ return Array.isArray(args.packWeightOverrides)
188
+ ? args.packWeightOverrides
189
+ : undefined;
190
+ }
191
+ function scopedTopicIdsForPlan(input, topicId, descendantDepth, args) {
192
+ const scopedTopicIds = collectTopicNeighborhood(input.allTopics, topicId, descendantDepth);
193
+ const allowedTopicIds = asStringArray(args.allowedTopicIds);
194
+ if (allowedTopicIds.length === 0) {
195
+ return scopedTopicIds;
196
+ }
197
+ const allowedSet = new Set(allowedTopicIds);
198
+ if (!allowedSet.has(topicId)) {
199
+ throw new Error(`Access denied to compile context for topic ${topicId}.`);
200
+ }
201
+ return scopedTopicIds.filter((id) => allowedSet.has(id));
202
+ }
147
203
  export function planContextPackCompilation(input) {
148
204
  const args = input.args ?? {};
149
205
  const topicId = String(input.topic._id);
150
- const queryText = typeof args.query === "string" && args.query.trim().length > 0
151
- ? args.query.trim()
152
- : undefined;
206
+ const queryText = optionalArgString(args, "query");
153
207
  const tokens = normalizeQueryTokens(queryText);
154
208
  const limit = toPositiveInt(args.limit, 8, 25);
155
- const rankingProfile = parseRankingProfile(typeof args.ranking === "string" ? args.ranking : args.rankingProfile);
156
- const tokenBudget = parseTokenBudget(typeof args.budget === "number" ? args.budget : args.tokenBudget, 1800);
157
- const topicDepth = typeof input.topic.depth === "number" && Number.isFinite(input.topic.depth)
158
- ? input.topic.depth
159
- : 0;
160
- const requestedMaxDepth = typeof args.maxDepth === "number" && Number.isFinite(args.maxDepth)
161
- ? Math.max(1, Math.min(Math.floor(args.maxDepth), 6))
162
- : undefined;
163
- const descendantDepth = requestedMaxDepth ?? (topicDepth <= 1 ? 4 : 2);
209
+ const rankingProfile = rankingProfileFromArgs(args);
210
+ const tokenBudget = tokenBudgetFromArgs(args);
211
+ const descendantDepth = descendantDepthFromArgs(args, input.topic);
164
212
  const includeEntities = args.includeEntities !== false;
165
213
  const compilationMode = args.mode === "delta" ? "delta" : DEFAULT_COMPILATION_MODE;
166
214
  const includeFailures = compilationMode === "delta" || args.includeFailures === true;
167
- const worktreeId = typeof args.worktreeId === "string" && args.worktreeId.trim().length > 0
168
- ? args.worktreeId.trim()
169
- : undefined;
170
- const sessionId = typeof args.sessionId === "string" && args.sessionId.trim().length > 0
171
- ? args.sessionId.trim()
172
- : undefined;
173
- const packWeightOverrides = Array.isArray(args.packWeightOverrides)
174
- ? args.packWeightOverrides
175
- : undefined;
215
+ const worktreeId = optionalArgString(args, "worktreeId");
216
+ const sessionId = optionalArgString(args, "sessionId");
217
+ const packWeightOverrides = packWeightOverridesFromArgs(args);
176
218
  const effectiveWeights = resolveEffectiveWeights(packWeightOverrides);
177
- let scopedTopicIds = collectTopicNeighborhood(input.allTopics, topicId, descendantDepth);
178
- const allowedTopicIds = asStringArray(args.allowedTopicIds);
179
- if (allowedTopicIds.length > 0) {
180
- const allowedSet = new Set(allowedTopicIds);
181
- if (!allowedSet.has(topicId)) {
182
- throw new Error(`Access denied to compile context for topic ${topicId}.`);
183
- }
184
- scopedTopicIds = scopedTopicIds.filter((id) => allowedSet.has(id));
185
- }
219
+ const scopedTopicIds = scopedTopicIdsForPlan(input, topicId, descendantDepth, args);
186
220
  return {
187
221
  topicId,
188
222
  ...(queryText ? { queryText } : {}),
@@ -201,17 +235,7 @@ export function planContextPackCompilation(input) {
201
235
  scopedTopicIds,
202
236
  };
203
237
  }
204
- export function compileContextPackFromSnapshot(snapshot) {
205
- const uniqueBeliefs = dedupeById(snapshot.beliefs);
206
- const uniqueQuestions = dedupeById(snapshot.questions);
207
- const uniqueEvidence = dedupeById(snapshot.evidence);
208
- const uniqueContradictions = dedupeById(snapshot.contradictions);
209
- const referenceTimeMs = resolveReferenceTimeMs([snapshot.topic], uniqueBeliefs, uniqueQuestions, uniqueEvidence, uniqueContradictions, snapshot.entities) || 0;
210
- const rankOptions = {
211
- effectiveWeights: snapshot.plan.effectiveWeights,
212
- includeJustifications: snapshot.plan.compilationMode === "delta",
213
- referenceTimeMs,
214
- };
238
+ function compileBeliefSections(uniqueBeliefs, plan, rankOptions) {
215
239
  const invariantCandidates = uniqueBeliefs
216
240
  .filter((belief) => beliefTypeOf(belief).toLowerCase() === "invariant")
217
241
  .map((belief) => ({
@@ -225,7 +249,7 @@ export function compileContextPackFromSnapshot(snapshot) {
225
249
  ...candidate,
226
250
  id: candidate.nodeId,
227
251
  text: `${candidate.canonicalText} ${candidate.beliefType}`,
228
- })), snapshot.plan.tokens, snapshot.plan.limit, snapshot.plan.rankingProfile, rankOptions).map((row) => ({
252
+ })), plan.tokens, plan.limit, plan.rankingProfile, rankOptions).map((row) => ({
229
253
  nodeId: row.nodeId,
230
254
  canonicalText: row.canonicalText,
231
255
  confidence: row.confidence,
@@ -250,7 +274,7 @@ export function compileContextPackFromSnapshot(snapshot) {
250
274
  ...candidate,
251
275
  id: candidate.nodeId,
252
276
  text: `${candidate.canonicalText} ${candidate.metadataText}`,
253
- })), snapshot.plan.tokens, snapshot.plan.limit, snapshot.plan.rankingProfile, rankOptions).map((row) => ({
277
+ })), plan.tokens, plan.limit, plan.rankingProfile, rankOptions).map((row) => ({
254
278
  nodeId: row.nodeId,
255
279
  canonicalText: row.canonicalText,
256
280
  confidence: row.confidence,
@@ -260,6 +284,14 @@ export function compileContextPackFromSnapshot(snapshot) {
260
284
  score: row.score,
261
285
  ...(row.justification ? { justification: row.justification } : {}),
262
286
  }));
287
+ return {
288
+ activeBeliefCandidates,
289
+ activeBeliefs,
290
+ invariantCandidates,
291
+ invariants,
292
+ };
293
+ }
294
+ function compileOpenQuestions(uniqueQuestions, plan, rankOptions) {
263
295
  const openQuestionCandidates = uniqueQuestions
264
296
  .map((question) => {
265
297
  const status = questionStatusOf(question);
@@ -280,7 +312,7 @@ export function compileContextPackFromSnapshot(snapshot) {
280
312
  ...candidate,
281
313
  id: candidate.questionId,
282
314
  text: `${candidate.text} ${candidate.metadataText}`,
283
- })), snapshot.plan.tokens, snapshot.plan.limit, snapshot.plan.rankingProfile, rankOptions).map((row) => ({
315
+ })), plan.tokens, plan.limit, plan.rankingProfile, rankOptions).map((row) => ({
284
316
  questionId: row.questionId,
285
317
  text: row.text,
286
318
  status: row.status,
@@ -289,6 +321,9 @@ export function compileContextPackFromSnapshot(snapshot) {
289
321
  score: row.score,
290
322
  ...(row.justification ? { justification: row.justification } : {}),
291
323
  }));
324
+ return { openQuestionCandidates, openQuestions };
325
+ }
326
+ function compileRecentEvidence(uniqueEvidence, plan, rankOptions) {
292
327
  const evidenceCandidates = uniqueEvidence.map((item) => {
293
328
  const metadata = item.metadata && typeof item.metadata === "object" ? item.metadata : {};
294
329
  return {
@@ -307,7 +342,7 @@ export function compileContextPackFromSnapshot(snapshot) {
307
342
  ...candidate,
308
343
  id: candidate.nodeId,
309
344
  text: `${candidate.canonicalText} ${candidate.metadataText}`,
310
- })), snapshot.plan.tokens, snapshot.plan.limit, snapshot.plan.rankingProfile, rankOptions).map((row) => ({
345
+ })), plan.tokens, plan.limit, plan.rankingProfile, rankOptions).map((row) => ({
311
346
  nodeId: row.nodeId,
312
347
  canonicalText: row.canonicalText,
313
348
  sourceUrl: row.sourceUrl,
@@ -316,18 +351,14 @@ export function compileContextPackFromSnapshot(snapshot) {
316
351
  score: row.score,
317
352
  ...(row.justification ? { justification: row.justification } : {}),
318
353
  }));
354
+ return { evidenceCandidates, recentEvidence };
355
+ }
356
+ function compileContradictions(uniqueContradictions, plan, rankOptions) {
319
357
  const contradictionCandidates = uniqueContradictions.map((row) => {
320
358
  const weight = typeof row.weight === "number" ? row.weight : 0;
321
- const severity = weight <= -0.9
322
- ? "critical"
323
- : weight <= -0.7
324
- ? "high"
325
- : weight <= -0.5
326
- ? "medium"
327
- : "low";
328
359
  return {
329
360
  contradictionId: String(row._id || row.globalId || ""),
330
- severity,
361
+ severity: contradictionSeverity(weight),
331
362
  status: "active",
332
363
  description: row.context || row.description || row.summary || "",
333
364
  updatedAt: row.updatedAt || row.createdAt || null,
@@ -337,7 +368,7 @@ export function compileContextPackFromSnapshot(snapshot) {
337
368
  ...candidate,
338
369
  id: candidate.contradictionId,
339
370
  text: `${candidate.description} ${candidate.severity}`,
340
- })), snapshot.plan.tokens, snapshot.plan.limit, snapshot.plan.rankingProfile, rankOptions).map((row) => ({
371
+ })), plan.tokens, plan.limit, plan.rankingProfile, rankOptions).map((row) => ({
341
372
  contradictionId: row.contradictionId,
342
373
  severity: row.severity,
343
374
  status: row.status,
@@ -345,85 +376,123 @@ export function compileContextPackFromSnapshot(snapshot) {
345
376
  score: row.score,
346
377
  ...(row.justification ? { justification: row.justification } : {}),
347
378
  }));
348
- const entityCandidates = snapshot.entities.map((row) => ({
379
+ return { contradictionCandidates, contradictions };
380
+ }
381
+ function compileEntities(entities, plan) {
382
+ const entityCandidates = entities.map((row) => ({
349
383
  nodeId: String(row._id),
350
384
  entityType: String(row.nodeType || ""),
351
385
  title: String(row.title || ""),
352
386
  canonicalText: String(row.canonicalText || ""),
353
- connectedBeliefCount: typeof row.connectedBeliefCount === "number" ? row.connectedBeliefCount : 0,
387
+ connectedBeliefCount: typeof row.connectedBeliefCount === "number"
388
+ ? row.connectedBeliefCount
389
+ : 0,
354
390
  connectedEvidenceCount: typeof row.connectedEvidenceCount === "number"
355
391
  ? row.connectedEvidenceCount
356
392
  : 0,
357
393
  metadata: row.metadata && typeof row.metadata === "object" ? row.metadata : {},
358
394
  updatedAt: row.updatedAt || null,
359
395
  }));
360
- const entityLimit = toPositiveInt(snapshot.plan.limit, DEFAULT_ENTITY_LIMIT, MAX_ENTITY_LIMIT);
361
- const rankedEntities = snapshot.plan.includeEntities
362
- ? rankEntities(entityCandidates, snapshot.plan.tokens, entityLimit).map((row) => ({
363
- nodeId: row.nodeId,
364
- entityType: row.entityType,
365
- title: row.title,
366
- connectedBeliefCount: row.connectedBeliefCount,
367
- connectedEvidenceCount: row.connectedEvidenceCount,
396
+ if (!plan.includeEntities) {
397
+ return { entityCandidates };
398
+ }
399
+ const entityLimit = toPositiveInt(plan.limit, DEFAULT_ENTITY_LIMIT, MAX_ENTITY_LIMIT);
400
+ const rankedEntities = rankEntities(entityCandidates, plan.tokens, entityLimit).map((row) => ({
401
+ nodeId: row.nodeId,
402
+ entityType: row.entityType,
403
+ title: row.title,
404
+ connectedBeliefCount: row.connectedBeliefCount,
405
+ connectedEvidenceCount: row.connectedEvidenceCount,
406
+ score: row.score,
407
+ ...(Object.keys(row.metadata).length > 0 ? { metadata: row.metadata } : {}),
408
+ }));
409
+ return { entityCandidates, rankedEntities };
410
+ }
411
+ function compileFailureContext(args) {
412
+ if (!(args.plan.includeFailures && args.failures)) {
413
+ return;
414
+ }
415
+ const allFailures = args.failures.filter((node) => {
416
+ const metadata = isRecord(node.metadata) ? node.metadata : {};
417
+ return (metadata.failedApproach === true || metadata.isFailedAttempt === true);
418
+ });
419
+ const rankedFailures = rankContextSection("recentEvidence", allFailures.map((node) => ({
420
+ id: String(node._id),
421
+ text: String(node.canonicalText || ""),
422
+ createdAt: node.createdAt || null,
423
+ updatedAt: node.updatedAt || node.createdAt || null,
424
+ })), args.plan.tokens, 10, args.plan.rankingProfile, args.rankOptions);
425
+ const failures = rankedFailures.map((row) => {
426
+ const original = allFailures.find((node) => String(node._id) === row.id);
427
+ const metadata = isRecord(original?.metadata) ? original?.metadata : {};
428
+ return {
429
+ attemptId: row.id,
430
+ approach: String(row.text || ""),
431
+ outcome: String(metadata.errorMessage || "Failed"),
432
+ recordedAt: row.createdAt || args.referenceTimeMs || 0,
368
433
  score: row.score,
369
- ...(Object.keys(row.metadata).length > 0
370
- ? { metadata: row.metadata }
371
- : {}),
372
- }))
373
- : undefined;
374
- let failureContext;
375
- if (snapshot.plan.includeFailures && snapshot.failures) {
376
- const allFailures = snapshot.failures.filter((node) => {
377
- const metadata = isRecord(node.metadata) ? node.metadata : {};
378
- return metadata.failedApproach === true || metadata.isFailedAttempt === true;
379
- });
380
- const rankedFailures = rankContextSection("recentEvidence", allFailures.map((node) => ({
381
- id: String(node._id),
382
- text: String(node.canonicalText || ""),
383
- createdAt: node.createdAt || null,
384
- updatedAt: node.updatedAt || node.createdAt || null,
385
- })), snapshot.plan.tokens, 10, snapshot.plan.rankingProfile, rankOptions);
386
- const failures = rankedFailures.map((row) => {
387
- const original = allFailures.find((node) => String(node._id) === row.id);
388
- const metadata = isRecord(original?.metadata) ? original?.metadata : {};
389
- return {
390
- attemptId: row.id,
391
- approach: String(row.text || ""),
392
- outcome: String(metadata.errorMessage || "Failed"),
393
- recordedAt: row.createdAt || referenceTimeMs || 0,
394
- score: row.score,
395
- };
396
- });
397
- const failureTexts = new Set(failures.map((failure) => failure.approach.toLowerCase().slice(0, 100)));
398
- const suppressionIds = new Set();
399
- if (snapshot.plan.sessionId && failureTexts.size > 0) {
400
- for (const evidenceRow of recentEvidence) {
401
- const evidenceText = evidenceRow.canonicalText.toLowerCase().slice(0, 100);
402
- for (const failureText of failureTexts) {
403
- if (evidenceText.includes(failureText) ||
404
- failureText.includes(evidenceText)) {
405
- suppressionIds.add(evidenceRow.nodeId);
406
- break;
407
- }
434
+ };
435
+ });
436
+ if (failures.length === 0) {
437
+ return;
438
+ }
439
+ const failureTexts = new Set(failures.map((failure) => failure.approach.toLowerCase().slice(0, 100)));
440
+ const suppressionIds = new Set();
441
+ if (args.plan.sessionId && failureTexts.size > 0) {
442
+ for (const evidenceRow of args.recentEvidence) {
443
+ const evidenceText = evidenceRow.canonicalText
444
+ .toLowerCase()
445
+ .slice(0, 100);
446
+ for (const failureText of failureTexts) {
447
+ if (evidenceText.includes(failureText) ||
448
+ failureText.includes(evidenceText)) {
449
+ suppressionIds.add(evidenceRow.nodeId);
450
+ break;
408
451
  }
409
452
  }
410
453
  }
411
- if (failures.length > 0) {
412
- failureContext = {
413
- failures,
414
- suppressedIds: Array.from(suppressionIds),
415
- };
416
- }
417
454
  }
455
+ return {
456
+ failures,
457
+ suppressedIds: Array.from(suppressionIds),
458
+ };
459
+ }
460
+ function applyFailureSuppression(recentEvidence, failureContext) {
418
461
  const suppressionSet = new Set(failureContext?.suppressedIds || []);
419
- const effectiveEvidence = suppressionSet.size > 0
420
- ? recentEvidence.filter((row) => !suppressionSet.has(row.nodeId))
421
- : recentEvidence;
422
- const suppressedEvidenceIds = suppressionSet.size > 0
423
- ? recentEvidence
462
+ if (suppressionSet.size === 0) {
463
+ return { effectiveEvidence: recentEvidence, suppressedEvidenceIds: [] };
464
+ }
465
+ return {
466
+ effectiveEvidence: recentEvidence.filter((row) => !suppressionSet.has(row.nodeId)),
467
+ suppressedEvidenceIds: recentEvidence
424
468
  .filter((row) => suppressionSet.has(row.nodeId))
425
- .map((row) => row.nodeId)
426
- : [];
469
+ .map((row) => row.nodeId),
470
+ };
471
+ }
472
+ export function compileContextPackFromSnapshot(snapshot) {
473
+ const uniqueBeliefs = dedupeById(snapshot.beliefs);
474
+ const uniqueQuestions = dedupeById(snapshot.questions);
475
+ const uniqueEvidence = dedupeById(snapshot.evidence);
476
+ const uniqueContradictions = dedupeById(snapshot.contradictions);
477
+ const referenceTimeMs = resolveReferenceTimeMs([snapshot.topic], uniqueBeliefs, uniqueQuestions, uniqueEvidence, uniqueContradictions, snapshot.entities) || 0;
478
+ const rankOptions = {
479
+ effectiveWeights: snapshot.plan.effectiveWeights,
480
+ includeJustifications: snapshot.plan.compilationMode === "delta",
481
+ referenceTimeMs,
482
+ };
483
+ const { activeBeliefCandidates, activeBeliefs, invariantCandidates, invariants, } = compileBeliefSections(uniqueBeliefs, snapshot.plan, rankOptions);
484
+ const { openQuestionCandidates, openQuestions } = compileOpenQuestions(uniqueQuestions, snapshot.plan, rankOptions);
485
+ const { evidenceCandidates, recentEvidence } = compileRecentEvidence(uniqueEvidence, snapshot.plan, rankOptions);
486
+ const { contradictionCandidates, contradictions } = compileContradictions(uniqueContradictions, snapshot.plan, rankOptions);
487
+ const { entityCandidates, rankedEntities } = compileEntities(snapshot.entities, snapshot.plan);
488
+ const failureContext = compileFailureContext({
489
+ failures: snapshot.failures,
490
+ plan: snapshot.plan,
491
+ rankOptions,
492
+ recentEvidence,
493
+ referenceTimeMs,
494
+ });
495
+ const { effectiveEvidence, suppressedEvidenceIds } = applyFailureSuppression(recentEvidence, failureContext);
427
496
  const summary = {
428
497
  totalBeliefs: uniqueBeliefs.length,
429
498
  invariants: invariants.length,
@@ -493,6 +562,7 @@ export function compileContextPackFromSnapshot(snapshot) {
493
562
  topicName: snapshot.topic.name || "Untitled Topic",
494
563
  scopedTopicIds: snapshot.plan.scopedTopicIds,
495
564
  generatedAt: referenceTimeMs,
565
+ ranking: snapshot.plan.rankingProfile,
496
566
  rankingProfile: snapshot.plan.rankingProfile,
497
567
  summary,
498
568
  invariants,
@@ -518,9 +588,9 @@ export function compileContextPackFromSnapshot(snapshot) {
518
588
  : Number((injectionPolicy.estimatedTokens / injectionPolicy.tokenBudget).toFixed(4)),
519
589
  referenceTimeMs,
520
590
  },
521
- ...(snapshot.plan.compilationMode !== "standard"
522
- ? { compilationMode: snapshot.plan.compilationMode }
523
- : {}),
591
+ ...(snapshot.plan.compilationMode === "standard"
592
+ ? {}
593
+ : { compilationMode: snapshot.plan.compilationMode }),
524
594
  ...(failureContext ? { failureContext } : {}),
525
595
  ...(deltaReport ? { deltaReport } : {}),
526
596
  ...(snapshot.plan.packWeightOverrides &&
@@ -1,38 +1,38 @@
1
- import { type PackWeightOverride, type RankingWeightVector, type ContextPackSectionKey, type ContextRankingProfile } from "./contracts/context-pack.contract";
1
+ import { type ContextPackSectionKey, type ContextRankingProfile, type PackWeightOverride, type RankingWeightVector } from "./contracts/context-pack.contract";
2
2
  export type SectionKey = ContextPackSectionKey;
3
- export type RankCandidate = {
4
- id: string;
5
- text: string;
6
- updatedAt?: number | null;
7
- createdAt?: number | null;
8
- confidence?: number | null;
3
+ export interface RankCandidate {
9
4
  beliefType?: string | null;
5
+ confidence?: number | null;
6
+ createdAt?: number | null;
7
+ id: string;
10
8
  priority?: string | null;
11
9
  severity?: string | null;
12
- };
10
+ text: string;
11
+ updatedAt?: number | null;
12
+ }
13
13
  export type RankedCandidate<T extends RankCandidate> = T & {
14
14
  score: number;
15
15
  justification?: string;
16
16
  };
17
- type LexicalExclusion = {
17
+ interface LexicalExclusion {
18
18
  id: string;
19
- section: SectionKey;
20
19
  reason: "budget_exceeded" | "anti_repetition" | "below_threshold";
21
20
  score: number;
22
- };
23
- export type InjectionPlan = {
24
- tokenBudget: number;
21
+ section: SectionKey;
22
+ }
23
+ export interface InjectionPlan {
25
24
  estimatedTokens: number;
25
+ excludedItems?: LexicalExclusion[];
26
26
  sectionBudgets: Record<SectionKey, number>;
27
27
  sectionUsage: Record<SectionKey, number>;
28
28
  selected: Record<SectionKey, string[]>;
29
- excludedItems?: LexicalExclusion[];
30
- };
31
- type RankContextOptions = {
29
+ tokenBudget: number;
30
+ }
31
+ interface RankContextOptions {
32
32
  effectiveWeights?: Readonly<Record<ContextPackSectionKey, RankingWeightVector>>;
33
33
  includeJustifications?: boolean;
34
34
  referenceTimeMs?: number;
35
- };
35
+ }
36
36
  export declare function resolveEffectiveWeights(overrides?: PackWeightOverride[]): Readonly<Record<ContextPackSectionKey, RankingWeightVector>>;
37
37
  export declare function rankContextSection<T extends RankCandidate>(section: SectionKey, rows: T[], queryTokens: string[], limit: number, profile: ContextRankingProfile, options?: RankContextOptions): RankedCandidate<T>[];
38
38
  export declare function parseTokenBudget(value: unknown, fallback?: number): number;
@@ -65,16 +65,16 @@ export declare function buildInjectionPlan(args: {
65
65
  }>;
66
66
  trackExclusions?: boolean;
67
67
  }): InjectionPlan;
68
- export type EntityCandidate = {
69
- nodeId: string;
70
- entityType: string;
71
- title: string;
68
+ export interface EntityCandidate {
72
69
  canonicalText: string;
73
70
  connectedBeliefCount: number;
74
71
  connectedEvidenceCount: number;
72
+ entityType: string;
75
73
  metadata: Record<string, unknown>;
74
+ nodeId: string;
75
+ title: string;
76
76
  updatedAt?: number | null;
77
- };
77
+ }
78
78
  export type RankedEntity = EntityCandidate & {
79
79
  score: number;
80
80
  };
@@ -1,4 +1,6 @@
1
- import { BELIEF_TYPE_BONUS, DEFAULT_ENTITY_LIMIT, DEFAULT_BELIEF_TYPE_BONUS, DEFAULT_PRIORITY_SCORE, DEFAULT_SEVERITY_SCORE, DEFAULT_TOKEN_BUDGET, ENTITY_RANKING_WEIGHTS, MAX_TOKEN_BUDGET, MAX_ENTITY_LIMIT, MIN_CONTRADICTION_BUDGET, MIN_TOKEN_BUDGET, MIN_TOKEN_ESTIMATE, PRIORITY_SCORES, RANKING_WEIGHTS, RECENCY_HALF_LIFE_DAYS, SECTION_BUDGET_RATIOS, SEVERITY_SCORES, TOKENS_PER_WORD, } from "./contracts/context-pack.contract.js";
1
+ // biome-ignore-all lint/style/useFilenamingConvention: This file is an @lucern/sdk public import ABI / package subpath compatibility surface; the camelCase filename is intentional.
2
+ import { BELIEF_TYPE_BONUS, DEFAULT_BELIEF_TYPE_BONUS, DEFAULT_ENTITY_LIMIT, DEFAULT_PRIORITY_SCORE, DEFAULT_SEVERITY_SCORE, DEFAULT_TOKEN_BUDGET, ENTITY_RANKING_WEIGHTS, MAX_ENTITY_LIMIT, MAX_TOKEN_BUDGET, MIN_CONTRADICTION_BUDGET, MIN_TOKEN_BUDGET, MIN_TOKEN_ESTIMATE, PRIORITY_SCORES, RANKING_WEIGHTS, RECENCY_HALF_LIFE_DAYS, SECTION_BUDGET_RATIOS, SEVERITY_SCORES, TOKENS_PER_WORD, } from "./contracts/context-pack.contract.js";
3
+ const TOKEN_SPLIT_PATTERN = /\s+/;
2
4
  function tokenHits(text, tokens) {
3
5
  if (tokens.length === 0) {
4
6
  return 1;
@@ -19,7 +21,7 @@ function clamp01(value) {
19
21
  return Math.max(0, Math.min(1, value));
20
22
  }
21
23
  function recencyScore(updatedAt, referenceTimeMs = Date.now()) {
22
- if (!updatedAt || !Number.isFinite(updatedAt)) {
24
+ if (!(updatedAt && Number.isFinite(updatedAt))) {
23
25
  return 0.25;
24
26
  }
25
27
  const ageMs = Math.max(0, referenceTimeMs - updatedAt);
@@ -58,15 +60,16 @@ export function resolveEffectiveWeights(overrides) {
58
60
  }
59
61
  return result;
60
62
  }
61
- function generateJustification(_section, candidate, queryTokens, weights) {
62
- const parts = [];
63
- const hits = tokenHits(candidate.text, queryTokens);
63
+ function appendQueryJustification(parts, text, queryTokens) {
64
+ const hits = tokenHits(text, queryTokens);
64
65
  if (queryTokens.length > 0 && hits > 0) {
65
66
  parts.push(`${hits}/${queryTokens.length} query terms matched`);
66
67
  }
67
68
  else if (queryTokens.length === 0) {
68
69
  parts.push("no query filter");
69
70
  }
71
+ }
72
+ function appendFreshnessJustification(parts, candidate) {
70
73
  const ts = candidate.updatedAt || candidate.createdAt || null;
71
74
  if (ts && Number.isFinite(ts)) {
72
75
  const ageDays = Math.max(0, Date.now() - ts) / (1000 * 60 * 60 * 24);
@@ -83,6 +86,8 @@ function generateJustification(_section, candidate, queryTokens, weights) {
83
86
  parts.push(`updated ${Math.floor(ageDays)}d ago (decayed)`);
84
87
  }
85
88
  }
89
+ }
90
+ function appendWeightedFieldJustifications(parts, candidate, weights) {
86
91
  if (weights.confidence !== undefined &&
87
92
  candidate.confidence !== null &&
88
93
  candidate.confidence !== undefined) {
@@ -97,8 +102,17 @@ function generateJustification(_section, candidate, queryTokens, weights) {
97
102
  if (weights.severity !== undefined && candidate.severity) {
98
103
  parts.push(`severity=${candidate.severity}`);
99
104
  }
105
+ }
106
+ function generateJustification(_section, candidate, queryTokens, weights) {
107
+ const parts = [];
108
+ appendQueryJustification(parts, candidate.text, queryTokens);
109
+ appendFreshnessJustification(parts, candidate);
110
+ appendWeightedFieldJustifications(parts, candidate, weights);
100
111
  return parts.join(", ");
101
112
  }
113
+ function computeBaselineScore(candidate, queryTokens) {
114
+ return queryTokens.length === 0 ? 1 : tokenHits(candidate.text, queryTokens);
115
+ }
102
116
  function computeWeightedScore(section, candidate, queryTokens, effectiveWeights, referenceTimeMs) {
103
117
  const weights = (effectiveWeights ?? RANKING_WEIGHTS)[section];
104
118
  const queryComponent = queryTokens.length === 0
@@ -127,9 +141,7 @@ export function rankContextSection(section, rows, queryTokens, limit, profile, o
127
141
  const scored = rows.map((row) => {
128
142
  const score = profile === "weighted_v1"
129
143
  ? computeWeightedScore(section, row, queryTokens, effectiveWeights, referenceTimeMs)
130
- : queryTokens.length === 0
131
- ? 1
132
- : tokenHits(row.text, queryTokens);
144
+ : computeBaselineScore(row, queryTokens);
133
145
  const result = { ...row, score };
134
146
  if (includeJustifications && profile === "weighted_v1") {
135
147
  const weights = (effectiveWeights ?? RANKING_WEIGHTS)[section];
@@ -155,7 +167,7 @@ export function parseTokenBudget(value, fallback = DEFAULT_TOKEN_BUDGET) {
155
167
  return Math.max(MIN_TOKEN_BUDGET, Math.min(MAX_TOKEN_BUDGET, parsed));
156
168
  }
157
169
  function estimateTokens(text) {
158
- const words = text.trim().split(/\s+/).filter(Boolean).length;
170
+ const words = text.trim().split(TOKEN_SPLIT_PATTERN).filter(Boolean).length;
159
171
  return Math.max(MIN_TOKEN_ESTIMATE, Math.ceil(words * TOKENS_PER_WORD));
160
172
  }
161
173
  export function buildInjectionPlan(args) {
@@ -1,7 +1,7 @@
1
- type ValidationResult = {
2
- valid: boolean;
1
+ interface ValidationResult {
3
2
  errors: string[];
4
- };
3
+ valid: boolean;
4
+ }
5
5
  export declare function validateContextPackSchema(payload: unknown): ValidationResult;
6
6
  export {};
7
7
  //# sourceMappingURL=contextPackSchema.d.ts.map
@@ -1,3 +1,4 @@
1
+ // biome-ignore-all lint/style/useFilenamingConvention: This file is an @lucern/sdk public import ABI / package subpath compatibility surface; the camelCase filename is intentional.
1
2
  const CONTEXT_PACK_SCHEMA_VERSION = "1.0.0";
2
3
  function isObject(value) {
3
4
  return typeof value === "object" && value !== null && !Array.isArray(value);