@claritylabs/cl-sdk 0.7.4 → 0.8.0

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.d.mts CHANGED
@@ -12,7 +12,16 @@ type GenerateText = (params: {
12
12
  text: string;
13
13
  usage?: TokenUsage;
14
14
  }>;
15
- /** Callback to generate a typed object from a prompt + Zod schema. Provider-agnostic. */
15
+ /**
16
+ * Callback to generate a typed object from a prompt + Zod schema. Provider-agnostic.
17
+ *
18
+ * The extraction pipeline passes document content via `providerOptions`:
19
+ * - `providerOptions.pdfBase64` — base64-encoded PDF to include as document context
20
+ * - `providerOptions.images` — `Array<{ imageBase64: string; mimeType: string }>` page images
21
+ *
22
+ * Your callback should check for these fields and include them as multi-part
23
+ * message content (e.g. file/image parts) when calling your AI provider.
24
+ */
16
25
  type GenerateObject<T = unknown> = (params: {
17
26
  prompt: string;
18
27
  system?: string;
package/dist/index.d.ts CHANGED
@@ -12,7 +12,16 @@ type GenerateText = (params: {
12
12
  text: string;
13
13
  usage?: TokenUsage;
14
14
  }>;
15
- /** Callback to generate a typed object from a prompt + Zod schema. Provider-agnostic. */
15
+ /**
16
+ * Callback to generate a typed object from a prompt + Zod schema. Provider-agnostic.
17
+ *
18
+ * The extraction pipeline passes document content via `providerOptions`:
19
+ * - `providerOptions.pdfBase64` — base64-encoded PDF to include as document context
20
+ * - `providerOptions.images` — `Array<{ imageBase64: string; mimeType: string }>` page images
21
+ *
22
+ * Your callback should check for these fields and include them as multi-part
23
+ * message content (e.g. file/image parts) when calling your AI provider.
24
+ */
16
25
  type GenerateObject<T = unknown> = (params: {
17
26
  prompt: string;
18
27
  system?: string;
package/dist/index.js CHANGED
@@ -1758,19 +1758,28 @@ async function runExtractor(params) {
1758
1758
  maxTokens = 4096,
1759
1759
  providerOptions
1760
1760
  } = params;
1761
- const pagesPdf = await extractPageRange(pdfBase64, startPage, endPage);
1762
- const fullPrompt = convertPdfToImages ? `${prompt}
1763
-
1764
- [Document pages ${startPage}-${endPage} are provided as images above.]` : `${prompt}
1761
+ const extractorProviderOptions = { ...providerOptions };
1762
+ let fullPrompt;
1763
+ if (convertPdfToImages) {
1764
+ const images = await convertPdfToImages(pdfBase64, startPage, endPage);
1765
+ extractorProviderOptions.images = images;
1766
+ fullPrompt = `${prompt}
1767
+
1768
+ [Document pages ${startPage}-${endPage} are provided as images.]`;
1769
+ } else {
1770
+ const pagesPdf = await extractPageRange(pdfBase64, startPage, endPage);
1771
+ extractorProviderOptions.pdfBase64 = pagesPdf;
1772
+ fullPrompt = `${prompt}
1765
1773
 
1766
- [Document pages ${startPage}-${endPage} are provided as a PDF file above.]`;
1774
+ [Document pages ${startPage}-${endPage} are provided as a PDF file.]`;
1775
+ }
1767
1776
  const strictSchema = toStrictSchema(schema);
1768
1777
  const result = await withRetry(
1769
1778
  () => generateObject({
1770
1779
  prompt: fullPrompt,
1771
1780
  schema: strictSchema,
1772
1781
  maxTokens,
1773
- providerOptions
1782
+ providerOptions: extractorProviderOptions
1774
1783
  })
1775
1784
  );
1776
1785
  return {
@@ -2849,29 +2858,73 @@ function getTemplate(policyType) {
2849
2858
  // src/prompts/coordinator/classify.ts
2850
2859
  var import_zod18 = require("zod");
2851
2860
  var ClassifyResultSchema = import_zod18.z.object({
2852
- documentType: import_zod18.z.enum(["policy", "quote"]),
2853
- policyTypes: import_zod18.z.array(PolicyTypeSchema),
2854
- confidence: import_zod18.z.number()
2861
+ documentType: import_zod18.z.enum(["policy", "quote"]).describe("Whether this is a bound policy or a proposed quote"),
2862
+ policyTypes: import_zod18.z.array(PolicyTypeSchema).min(1).describe("Lines of business covered \u2014 at least one required"),
2863
+ confidence: import_zod18.z.number().describe("Confidence score from 0.0 to 1.0")
2855
2864
  });
2856
2865
  function buildClassifyPrompt() {
2857
- return `You are classifying an insurance document. Examine the first few pages and determine:
2866
+ return `You are classifying an insurance document. Examine the document and determine:
2858
2867
 
2859
2868
  1. Whether this is a POLICY (bound coverage) or QUOTE (proposed coverage)
2860
- 2. What lines of business are covered
2861
-
2862
- Policies typically have: policy numbers, effective/expiration dates, declarations pages, premium charges.
2863
- Quotes typically have: quote numbers, proposed dates, subjectivities, "indication" or "proposal" language.
2864
-
2865
- Return JSON matching this structure:
2869
+ 2. What lines of business are covered (at least one \u2014 never return an empty list)
2870
+
2871
+ POLICY indicators: policy numbers, effective/expiration dates, declarations pages, premium charges, "this policy" language.
2872
+ QUOTE indicators: quote numbers, proposed dates, subjectivities, "indication" or "proposal" language, "quoted premium".
2873
+
2874
+ COMMERCIAL LINES \u2014 match these values:
2875
+ - "general_liability" \u2014 CGL, commercial general liability, GL
2876
+ - "commercial_property" \u2014 commercial property, building/contents coverage
2877
+ - "commercial_auto" \u2014 commercial auto, business auto, CA
2878
+ - "non_owned_auto" \u2014 hired & non-owned auto
2879
+ - "workers_comp" \u2014 workers compensation, WC
2880
+ - "umbrella" \u2014 commercial umbrella
2881
+ - "excess_liability" \u2014 excess liability, follow-form excess
2882
+ - "professional_liability" \u2014 E&O, errors & omissions, professional liability, malpractice
2883
+ - "cyber" \u2014 cyber liability, data breach, network security
2884
+ - "epli" \u2014 employment practices liability
2885
+ - "directors_officers" \u2014 D&O, directors and officers
2886
+ - "fiduciary_liability" \u2014 fiduciary liability
2887
+ - "crime_fidelity" \u2014 crime, fidelity, employee dishonesty
2888
+ - "inland_marine" \u2014 inland marine, equipment floater, contractors equipment
2889
+ - "builders_risk" \u2014 builders risk, course of construction
2890
+ - "environmental" \u2014 environmental, pollution liability
2891
+ - "ocean_marine" \u2014 ocean marine, cargo, hull
2892
+ - "surety" \u2014 surety bond
2893
+ - "product_liability" \u2014 product liability, products-completed operations
2894
+ - "bop" \u2014 business owners policy, BOP
2895
+ - "management_liability_package" \u2014 management liability package
2896
+ - "property" \u2014 standalone property
2897
+
2898
+ PERSONAL LINES \u2014 match these values:
2899
+ - "homeowners_ho3" \u2014 HO-3, special form homeowners
2900
+ - "homeowners_ho5" \u2014 HO-5, comprehensive form homeowners
2901
+ - "renters_ho4" \u2014 HO-4, renters insurance
2902
+ - "condo_ho6" \u2014 HO-6, condo unit-owners
2903
+ - "dwelling_fire" \u2014 DP-1, DP-3, dwelling fire
2904
+ - "mobile_home" \u2014 mobile home, manufactured home
2905
+ - "personal_auto" \u2014 personal auto, PAP
2906
+ - "personal_umbrella" \u2014 personal umbrella
2907
+ - "flood_nfip" \u2014 NFIP flood
2908
+ - "flood_private" \u2014 private flood
2909
+ - "earthquake" \u2014 earthquake
2910
+ - "personal_inland_marine" \u2014 personal articles, scheduled personal property
2911
+ - "watercraft" \u2014 watercraft, boat
2912
+ - "recreational_vehicle" \u2014 RV, recreational vehicle, ATV
2913
+ - "farm_ranch" \u2014 farm, ranch
2914
+ - "pet" \u2014 pet insurance
2915
+ - "travel" \u2014 travel insurance
2916
+ - "identity_theft" \u2014 identity theft
2917
+ - "title" \u2014 title insurance
2918
+ - "other" \u2014 only if NONE of the above match
2919
+
2920
+ IMPORTANT: You must identify at least one specific policy type. Only use "other" as a last resort when the document truly does not match any known type.
2921
+
2922
+ Return JSON only:
2866
2923
  {
2867
2924
  "documentType": "policy" | "quote",
2868
- "policyTypes": ["general_liability", "commercial_property", ...],
2925
+ "policyTypes": ["general_liability", ...],
2869
2926
  "confidence": 0.0-1.0
2870
- }
2871
-
2872
- Use these policy type values: general_liability, commercial_property, commercial_auto, non_owned_auto, workers_comp, umbrella, excess_liability, professional_liability, cyber, epli, directors_officers, fiduciary_liability, crime_fidelity, inland_marine, builders_risk, environmental, ocean_marine, surety, product_liability, bop, management_liability_package, property, homeowners_ho3, homeowners_ho5, renters_ho4, condo_ho6, dwelling_fire, mobile_home, personal_auto, personal_umbrella, flood_nfip, flood_private, earthquake, personal_inland_marine, watercraft, recreational_vehicle, farm_ranch, pet, travel, identity_theft, title, other.
2873
-
2874
- Respond with JSON only.`;
2927
+ }`;
2875
2928
  }
2876
2929
 
2877
2930
  // src/prompts/coordinator/plan.ts
@@ -3546,16 +3599,20 @@ function createExtractor(config) {
3546
3599
  prompt: buildClassifyPrompt(),
3547
3600
  schema: ClassifyResultSchema,
3548
3601
  maxTokens: 512,
3549
- providerOptions
3602
+ providerOptions: { ...providerOptions, pdfBase64 }
3550
3603
  },
3551
3604
  {
3552
3605
  fallback: { documentType: "policy", policyTypes: ["other"], confidence: 0 },
3606
+ maxRetries: 3,
3553
3607
  log,
3554
- onError: (err, attempt) => log?.(`Classify attempt ${attempt + 1} failed: ${err}`)
3608
+ onError: (err, attempt) => log?.(`Classify attempt ${attempt + 1} failed: ${err instanceof Error ? err.message : String(err)}`)
3555
3609
  }
3556
3610
  );
3557
3611
  trackUsage(classifyResponse.usage);
3558
3612
  classifyResult = classifyResponse.object;
3613
+ if (classifyResult.confidence === 0) {
3614
+ await log?.(`WARNING: classify returned fallback (policyTypes: ["other"]). This usually means the generateObject callback failed \u2014 check that the document content is accessible to the model.`);
3615
+ }
3559
3616
  memory.set("classify", classifyResult);
3560
3617
  await pipelineCtx.save("classify", {
3561
3618
  id,
@@ -3586,7 +3643,7 @@ function createExtractor(config) {
3586
3643
  prompt: buildPlanPrompt(templateHints),
3587
3644
  schema: ExtractionPlanSchema,
3588
3645
  maxTokens: 2048,
3589
- providerOptions
3646
+ providerOptions: { ...providerOptions, pdfBase64 }
3590
3647
  },
3591
3648
  {
3592
3649
  fallback: {