@claritylabs/cl-sdk 3.0.2 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +107 -30
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +107 -30
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -8890,6 +8890,8 @@ var ORGANIZABLE_KINDS = [
|
|
|
8890
8890
|
"schedule",
|
|
8891
8891
|
"clause"
|
|
8892
8892
|
];
|
|
8893
|
+
var ORGANIZATION_TOP_LEVEL_BATCH_SIZE = 80;
|
|
8894
|
+
var ORGANIZATION_CHILD_CONTEXT_LIMIT = 4;
|
|
8893
8895
|
var SourceTreeOrganizationSchema = z41.object({
|
|
8894
8896
|
labels: z41.array(z41.object({
|
|
8895
8897
|
nodeId: z41.string(),
|
|
@@ -8954,7 +8956,7 @@ function cleanText(value, fallback) {
|
|
|
8954
8956
|
const text = value?.replace(/\s+/g, " ").trim();
|
|
8955
8957
|
return text || fallback;
|
|
8956
8958
|
}
|
|
8957
|
-
function compactNode(node) {
|
|
8959
|
+
function compactNode(node, maxText = 700) {
|
|
8958
8960
|
return {
|
|
8959
8961
|
id: node.id,
|
|
8960
8962
|
kind: node.kind,
|
|
@@ -8963,20 +8965,89 @@ function compactNode(node) {
|
|
|
8963
8965
|
pageStart: node.pageStart,
|
|
8964
8966
|
pageEnd: node.pageEnd,
|
|
8965
8967
|
sourceSpanIds: node.sourceSpanIds.slice(0, 8),
|
|
8966
|
-
text: (node.textExcerpt ?? node.description).slice(0,
|
|
8968
|
+
text: (node.textExcerpt ?? node.description).slice(0, maxText)
|
|
8967
8969
|
};
|
|
8968
8970
|
}
|
|
8969
|
-
function
|
|
8970
|
-
const
|
|
8971
|
+
function nodesByParent(sourceTree) {
|
|
8972
|
+
const byParent = /* @__PURE__ */ new Map();
|
|
8973
|
+
for (const node of sourceTree) {
|
|
8974
|
+
const children = byParent.get(node.parentId) ?? [];
|
|
8975
|
+
children.push(node);
|
|
8976
|
+
byParent.set(node.parentId, children);
|
|
8977
|
+
}
|
|
8978
|
+
for (const children of byParent.values()) {
|
|
8979
|
+
children.sort((left, right) => left.order - right.order || left.id.localeCompare(right.id));
|
|
8980
|
+
}
|
|
8981
|
+
return byParent;
|
|
8982
|
+
}
|
|
8983
|
+
function sourceTreeRootId(sourceTree) {
|
|
8984
|
+
return sourceTree.find((node) => node.kind === "document")?.id;
|
|
8985
|
+
}
|
|
8986
|
+
function organizationBatches(sourceTree) {
|
|
8987
|
+
const byParent = nodesByParent(sourceTree);
|
|
8988
|
+
const rootId = sourceTreeRootId(sourceTree);
|
|
8989
|
+
const topLevelNodes = (byParent.get(rootId) ?? []).filter((node) => node.kind !== "document");
|
|
8990
|
+
if (topLevelNodes.length === 0) {
|
|
8991
|
+
const nodes = sourceTree.filter((node) => node.kind !== "document").slice(0, 240);
|
|
8992
|
+
return [{
|
|
8993
|
+
label: "fallback node prefix because no document root children were found",
|
|
8994
|
+
topLevelNodeIds: nodes.map((node) => node.id),
|
|
8995
|
+
nodes
|
|
8996
|
+
}];
|
|
8997
|
+
}
|
|
8998
|
+
const batches = [];
|
|
8999
|
+
for (let index = 0; index < topLevelNodes.length; index += ORGANIZATION_TOP_LEVEL_BATCH_SIZE) {
|
|
9000
|
+
const topLevelBatch = topLevelNodes.slice(index, index + ORGANIZATION_TOP_LEVEL_BATCH_SIZE);
|
|
9001
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
9002
|
+
for (const node of topLevelBatch) {
|
|
9003
|
+
candidates.set(node.id, node);
|
|
9004
|
+
const childContext = (byParent.get(node.id) ?? []).filter((child) => child.kind !== "text" && child.kind !== "table_cell").slice(0, ORGANIZATION_CHILD_CONTEXT_LIMIT);
|
|
9005
|
+
for (const child of childContext) {
|
|
9006
|
+
candidates.set(child.id, child);
|
|
9007
|
+
}
|
|
9008
|
+
}
|
|
9009
|
+
batches.push({
|
|
9010
|
+
label: `top-level nodes ${index + 1}-${index + topLevelBatch.length} of ${topLevelNodes.length}`,
|
|
9011
|
+
topLevelNodeIds: topLevelBatch.map((node) => node.id),
|
|
9012
|
+
nodes: [...candidates.values()]
|
|
9013
|
+
});
|
|
9014
|
+
}
|
|
9015
|
+
return batches;
|
|
9016
|
+
}
|
|
9017
|
+
function mergeOrganizationResults(results) {
|
|
9018
|
+
const labels = /* @__PURE__ */ new Map();
|
|
9019
|
+
const groups = /* @__PURE__ */ new Map();
|
|
9020
|
+
for (const result of results) {
|
|
9021
|
+
for (const label of result.labels) {
|
|
9022
|
+
labels.set(label.nodeId, { ...labels.get(label.nodeId), ...label });
|
|
9023
|
+
}
|
|
9024
|
+
for (const group of result.groups) {
|
|
9025
|
+
const key = `${group.kind}:${group.childNodeIds.join("|")}`;
|
|
9026
|
+
groups.set(key, group);
|
|
9027
|
+
}
|
|
9028
|
+
}
|
|
9029
|
+
return {
|
|
9030
|
+
labels: [...labels.values()],
|
|
9031
|
+
groups: [...groups.values()]
|
|
9032
|
+
};
|
|
9033
|
+
}
|
|
9034
|
+
function buildOrganizationPrompt(batch) {
|
|
9035
|
+
const nodes = batch.nodes.map((node) => compactNode(node, node.kind === "page" ? 900 : 320));
|
|
8971
9036
|
return `You organize an insurance document source tree.
|
|
8972
9037
|
|
|
9038
|
+
Scope:
|
|
9039
|
+
- ${batch.label}
|
|
9040
|
+
- The provided list is a bounded extraction-time batch. It is not necessarily the whole document.
|
|
9041
|
+
- Top-level page/form candidates in this batch: ${JSON.stringify(batch.topLevelNodeIds)}
|
|
9042
|
+
|
|
8973
9043
|
Rules:
|
|
8974
9044
|
- Use only node IDs from the provided list.
|
|
8975
9045
|
- Do not invent text, page numbers, source spans, limits, or policy facts.
|
|
8976
|
-
- You may relabel existing nodes and group adjacent top-level/page nodes when they are clearly one form, endorsement, declarations set, schedule, or clause family.
|
|
9046
|
+
- You may relabel existing nodes and group adjacent top-level/page nodes from this batch when they are clearly one form, endorsement, declarations set, schedule, or clause family.
|
|
8977
9047
|
- Add concise, human-readable titles to generic text, table, row, and cell nodes when the text makes their role clear.
|
|
8978
9048
|
- Groups must list existing childNodeIds only.
|
|
8979
9049
|
- Keep descriptions short and useful for search.
|
|
9050
|
+
- Prefer the document's own form titles, endorsement titles, schedules, declarations headings, and page order over keyword-only guessing.
|
|
8980
9051
|
|
|
8981
9052
|
Source nodes:
|
|
8982
9053
|
${JSON.stringify(nodes, null, 2)}
|
|
@@ -9016,8 +9087,9 @@ function groupNodeId(documentId, group) {
|
|
|
9016
9087
|
}
|
|
9017
9088
|
function applyOrganization(sourceTree, organization) {
|
|
9018
9089
|
const byId = new Map(sourceTree.map((node) => [node.id, node]));
|
|
9090
|
+
const labels = new Map(organization.labels.map((label) => [label.nodeId, label]));
|
|
9019
9091
|
let nextTree = sourceTree.map((node) => {
|
|
9020
|
-
const label =
|
|
9092
|
+
const label = labels.get(node.id);
|
|
9021
9093
|
if (!label) return node;
|
|
9022
9094
|
return {
|
|
9023
9095
|
...node,
|
|
@@ -9026,7 +9098,7 @@ function applyOrganization(sourceTree, organization) {
|
|
|
9026
9098
|
description: cleanText(label.description, node.description)
|
|
9027
9099
|
};
|
|
9028
9100
|
});
|
|
9029
|
-
for (const group of organization.groups
|
|
9101
|
+
for (const group of organization.groups) {
|
|
9030
9102
|
const children = group.childNodeIds.map((id2) => byId.get(id2)).filter((node2) => Boolean(node2));
|
|
9031
9103
|
if (children.length === 0) continue;
|
|
9032
9104
|
const parentId = children[0].parentId;
|
|
@@ -9208,30 +9280,35 @@ async function runSourceTreeExtraction(params) {
|
|
|
9208
9280
|
params.trackUsage(usage, report);
|
|
9209
9281
|
};
|
|
9210
9282
|
try {
|
|
9211
|
-
const
|
|
9212
|
-
const
|
|
9213
|
-
const
|
|
9214
|
-
params.
|
|
9215
|
-
|
|
9216
|
-
|
|
9217
|
-
|
|
9218
|
-
|
|
9283
|
+
const organizations = [];
|
|
9284
|
+
const batches = organizationBatches(sourceTree);
|
|
9285
|
+
for (const [batchIndex, batch] of batches.entries()) {
|
|
9286
|
+
const budget = params.resolveBudget("extraction_source_tree", 4096);
|
|
9287
|
+
const startedAt = Date.now();
|
|
9288
|
+
const response = await safeGenerateObject(
|
|
9289
|
+
params.generateObject,
|
|
9290
|
+
{
|
|
9291
|
+
prompt: buildOrganizationPrompt(batch),
|
|
9292
|
+
schema: SourceTreeOrganizationSchema,
|
|
9293
|
+
maxTokens: budget.maxTokens,
|
|
9294
|
+
taskKind: "extraction_source_tree",
|
|
9295
|
+
budgetDiagnostics: budget,
|
|
9296
|
+
providerOptions: { ...params.providerOptions, sourceSpans: params.sourceSpans }
|
|
9297
|
+
},
|
|
9298
|
+
{
|
|
9299
|
+
fallback: { labels: [], groups: [] },
|
|
9300
|
+
log: params.log
|
|
9301
|
+
}
|
|
9302
|
+
);
|
|
9303
|
+
localTrack(response.usage, {
|
|
9219
9304
|
taskKind: "extraction_source_tree",
|
|
9220
|
-
|
|
9221
|
-
|
|
9222
|
-
|
|
9223
|
-
|
|
9224
|
-
|
|
9225
|
-
|
|
9226
|
-
|
|
9227
|
-
);
|
|
9228
|
-
localTrack(response.usage, {
|
|
9229
|
-
taskKind: "extraction_source_tree",
|
|
9230
|
-
label: "source_tree_organizer",
|
|
9231
|
-
maxTokens: budget.maxTokens,
|
|
9232
|
-
durationMs: Date.now() - startedAt
|
|
9233
|
-
});
|
|
9234
|
-
sourceTree = applyOrganization(sourceTree, response.object);
|
|
9305
|
+
label: batches.length > 1 ? `source_tree_organizer_${batchIndex + 1}` : "source_tree_organizer",
|
|
9306
|
+
maxTokens: budget.maxTokens,
|
|
9307
|
+
durationMs: Date.now() - startedAt
|
|
9308
|
+
});
|
|
9309
|
+
organizations.push(response.object);
|
|
9310
|
+
}
|
|
9311
|
+
sourceTree = applyOrganization(sourceTree, mergeOrganizationResults(organizations));
|
|
9235
9312
|
} catch (error) {
|
|
9236
9313
|
warnings.push(`Source-tree organizer failed; deterministic tree used (${error instanceof Error ? error.message : String(error)})`);
|
|
9237
9314
|
}
|