@claritylabs/cl-sdk 0.7.3 → 0.7.5

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 CHANGED
@@ -333,29 +333,40 @@ function toStrictSchema(schema) {
333
333
  const fieldType = fieldDef?.type ?? field.type;
334
334
  if (fieldType === "optional") {
335
335
  const innerType = fieldDef?.innerType;
336
+ const description = field.description ?? fieldDef?.description ?? field._zod?.def?.description;
336
337
  if (innerType) {
337
338
  const transformed = toStrictSchema(innerType);
338
- newShape[key] = import_zod.z.nullable(transformed);
339
+ let nullable = import_zod.z.nullable(transformed);
340
+ if (description) nullable = nullable.describe(description);
341
+ newShape[key] = nullable;
339
342
  } else {
340
- newShape[key] = import_zod.z.nullable(field);
343
+ let nullable = import_zod.z.nullable(field);
344
+ if (description) nullable = nullable.describe(description);
345
+ newShape[key] = nullable;
341
346
  }
342
347
  } else {
343
348
  newShape[key] = toStrictSchema(field);
344
349
  }
345
350
  }
346
- return import_zod.z.object(newShape);
351
+ const objDesc = schema.description ?? def?.description ?? schema._zod?.def?.description;
352
+ const result = import_zod.z.object(newShape);
353
+ return objDesc ? result.describe(objDesc) : result;
347
354
  }
348
355
  if (typeName === "array") {
349
356
  const element = def?.element ?? schema.element;
350
357
  if (element) {
351
- return import_zod.z.array(toStrictSchema(element));
358
+ const arrDesc = schema.description ?? def?.description ?? schema._zod?.def?.description;
359
+ const result = import_zod.z.array(toStrictSchema(element));
360
+ return arrDesc ? result.describe(arrDesc) : result;
352
361
  }
353
362
  return schema;
354
363
  }
355
364
  if (typeName === "nullable") {
356
365
  const innerType = def?.innerType;
357
366
  if (innerType) {
358
- return import_zod.z.nullable(toStrictSchema(innerType));
367
+ const nullDesc = schema.description ?? def?.description ?? schema._zod?.def?.description;
368
+ const result = import_zod.z.nullable(toStrictSchema(innerType));
369
+ return nullDesc ? result.describe(nullDesc) : result;
359
370
  }
360
371
  return schema;
361
372
  }
@@ -2838,29 +2849,73 @@ function getTemplate(policyType) {
2838
2849
  // src/prompts/coordinator/classify.ts
2839
2850
  var import_zod18 = require("zod");
2840
2851
  var ClassifyResultSchema = import_zod18.z.object({
2841
- documentType: import_zod18.z.enum(["policy", "quote"]),
2842
- policyTypes: import_zod18.z.array(PolicyTypeSchema),
2843
- confidence: import_zod18.z.number()
2852
+ documentType: import_zod18.z.enum(["policy", "quote"]).describe("Whether this is a bound policy or a proposed quote"),
2853
+ policyTypes: import_zod18.z.array(PolicyTypeSchema).min(1).describe("Lines of business covered \u2014 at least one required"),
2854
+ confidence: import_zod18.z.number().describe("Confidence score from 0.0 to 1.0")
2844
2855
  });
2845
2856
  function buildClassifyPrompt() {
2846
- return `You are classifying an insurance document. Examine the first few pages and determine:
2857
+ return `You are classifying an insurance document. Examine the document and determine:
2847
2858
 
2848
2859
  1. Whether this is a POLICY (bound coverage) or QUOTE (proposed coverage)
2849
- 2. What lines of business are covered
2850
-
2851
- Policies typically have: policy numbers, effective/expiration dates, declarations pages, premium charges.
2852
- Quotes typically have: quote numbers, proposed dates, subjectivities, "indication" or "proposal" language.
2853
-
2854
- Return JSON matching this structure:
2860
+ 2. What lines of business are covered (at least one \u2014 never return an empty list)
2861
+
2862
+ POLICY indicators: policy numbers, effective/expiration dates, declarations pages, premium charges, "this policy" language.
2863
+ QUOTE indicators: quote numbers, proposed dates, subjectivities, "indication" or "proposal" language, "quoted premium".
2864
+
2865
+ COMMERCIAL LINES \u2014 match these values:
2866
+ - "general_liability" \u2014 CGL, commercial general liability, GL
2867
+ - "commercial_property" \u2014 commercial property, building/contents coverage
2868
+ - "commercial_auto" \u2014 commercial auto, business auto, CA
2869
+ - "non_owned_auto" \u2014 hired & non-owned auto
2870
+ - "workers_comp" \u2014 workers compensation, WC
2871
+ - "umbrella" \u2014 commercial umbrella
2872
+ - "excess_liability" \u2014 excess liability, follow-form excess
2873
+ - "professional_liability" \u2014 E&O, errors & omissions, professional liability, malpractice
2874
+ - "cyber" \u2014 cyber liability, data breach, network security
2875
+ - "epli" \u2014 employment practices liability
2876
+ - "directors_officers" \u2014 D&O, directors and officers
2877
+ - "fiduciary_liability" \u2014 fiduciary liability
2878
+ - "crime_fidelity" \u2014 crime, fidelity, employee dishonesty
2879
+ - "inland_marine" \u2014 inland marine, equipment floater, contractors equipment
2880
+ - "builders_risk" \u2014 builders risk, course of construction
2881
+ - "environmental" \u2014 environmental, pollution liability
2882
+ - "ocean_marine" \u2014 ocean marine, cargo, hull
2883
+ - "surety" \u2014 surety bond
2884
+ - "product_liability" \u2014 product liability, products-completed operations
2885
+ - "bop" \u2014 business owners policy, BOP
2886
+ - "management_liability_package" \u2014 management liability package
2887
+ - "property" \u2014 standalone property
2888
+
2889
+ PERSONAL LINES \u2014 match these values:
2890
+ - "homeowners_ho3" \u2014 HO-3, special form homeowners
2891
+ - "homeowners_ho5" \u2014 HO-5, comprehensive form homeowners
2892
+ - "renters_ho4" \u2014 HO-4, renters insurance
2893
+ - "condo_ho6" \u2014 HO-6, condo unit-owners
2894
+ - "dwelling_fire" \u2014 DP-1, DP-3, dwelling fire
2895
+ - "mobile_home" \u2014 mobile home, manufactured home
2896
+ - "personal_auto" \u2014 personal auto, PAP
2897
+ - "personal_umbrella" \u2014 personal umbrella
2898
+ - "flood_nfip" \u2014 NFIP flood
2899
+ - "flood_private" \u2014 private flood
2900
+ - "earthquake" \u2014 earthquake
2901
+ - "personal_inland_marine" \u2014 personal articles, scheduled personal property
2902
+ - "watercraft" \u2014 watercraft, boat
2903
+ - "recreational_vehicle" \u2014 RV, recreational vehicle, ATV
2904
+ - "farm_ranch" \u2014 farm, ranch
2905
+ - "pet" \u2014 pet insurance
2906
+ - "travel" \u2014 travel insurance
2907
+ - "identity_theft" \u2014 identity theft
2908
+ - "title" \u2014 title insurance
2909
+ - "other" \u2014 only if NONE of the above match
2910
+
2911
+ 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.
2912
+
2913
+ Return JSON only:
2855
2914
  {
2856
2915
  "documentType": "policy" | "quote",
2857
- "policyTypes": ["general_liability", "commercial_property", ...],
2916
+ "policyTypes": ["general_liability", ...],
2858
2917
  "confidence": 0.0-1.0
2859
- }
2860
-
2861
- 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.
2862
-
2863
- Respond with JSON only.`;
2918
+ }`;
2864
2919
  }
2865
2920
 
2866
2921
  // src/prompts/coordinator/plan.ts
@@ -3079,27 +3134,71 @@ var import_zod24 = require("zod");
3079
3134
  var EndorsementsSchema = import_zod24.z.object({
3080
3135
  endorsements: import_zod24.z.array(
3081
3136
  import_zod24.z.object({
3082
- formNumber: import_zod24.z.string().optional().describe("Form number, e.g. 'CG 21 47'"),
3083
- title: import_zod24.z.string().optional().describe("Endorsement title"),
3084
- type: import_zod24.z.enum(["broadening", "restrictive", "informational"]).optional().describe("Effect type: broadening adds coverage, restrictive limits it"),
3085
- content: import_zod24.z.string().optional().describe("Full verbatim text of the endorsement"),
3137
+ formNumber: import_zod24.z.string().describe("Form number, e.g. 'CG 21 47'"),
3138
+ editionDate: import_zod24.z.string().optional().describe("Edition date, e.g. '12 07'"),
3139
+ title: import_zod24.z.string().describe("Endorsement title"),
3140
+ endorsementType: import_zod24.z.enum([
3141
+ "additional_insured",
3142
+ "waiver_of_subrogation",
3143
+ "primary_noncontributory",
3144
+ "blanket_additional_insured",
3145
+ "loss_payee",
3146
+ "mortgage_holder",
3147
+ "broadening",
3148
+ "restriction",
3149
+ "exclusion",
3150
+ "amendatory",
3151
+ "notice_of_cancellation",
3152
+ "designated_premises",
3153
+ "classification_change",
3154
+ "schedule_update",
3155
+ "deductible_change",
3156
+ "limit_change",
3157
+ "territorial_extension",
3158
+ "other"
3159
+ ]).describe("Endorsement type classification"),
3086
3160
  effectiveDate: import_zod24.z.string().optional().describe("Endorsement effective date"),
3087
- premium: import_zod24.z.string().optional().describe("Additional premium or credit"),
3088
- parties: import_zod24.z.array(import_zod24.z.string()).optional().describe("Named parties (additional insureds, loss payees, etc.)")
3161
+ affectedCoverageParts: import_zod24.z.array(import_zod24.z.string()).optional().describe("Coverage parts affected by this endorsement"),
3162
+ namedParties: import_zod24.z.array(
3163
+ import_zod24.z.object({
3164
+ name: import_zod24.z.string().describe("Party name"),
3165
+ role: import_zod24.z.enum([
3166
+ "additional_insured",
3167
+ "loss_payee",
3168
+ "mortgage_holder",
3169
+ "certificate_holder",
3170
+ "waiver_beneficiary",
3171
+ "designated_person",
3172
+ "other"
3173
+ ]).describe("Party role"),
3174
+ relationship: import_zod24.z.string().optional().describe("Relationship to insured"),
3175
+ scope: import_zod24.z.string().optional().describe("Scope of coverage for this party")
3176
+ })
3177
+ ).optional().describe("Named parties (additional insureds, loss payees, etc.)"),
3178
+ keyTerms: import_zod24.z.array(import_zod24.z.string()).optional().describe("Key terms or notable provisions in the endorsement"),
3179
+ premiumImpact: import_zod24.z.string().optional().describe("Additional premium or credit"),
3180
+ content: import_zod24.z.string().describe("Full verbatim text of the endorsement"),
3181
+ pageStart: import_zod24.z.number().describe("Starting page number of this endorsement"),
3182
+ pageEnd: import_zod24.z.number().optional().describe("Ending page number of this endorsement")
3089
3183
  })
3090
3184
  ).describe("All endorsements found in the document")
3091
3185
  });
3092
3186
  function buildEndorsementsPrompt() {
3093
3187
  return `You are an expert insurance document analyst. Extract ALL endorsements from this document. Preserve original language verbatim.
3094
3188
 
3095
- Focus on:
3096
- - Every endorsement listed in the forms schedule or endorsement schedule
3097
- - Standalone endorsements modifying the base policy
3098
- - Form number and edition date (e.g. "CG 21 47 12 07")
3099
- - Endorsement title and full verbatim content
3100
- - Effect type: "broadening" if it adds or expands coverage, "restrictive" if it limits or excludes coverage, "informational" if it changes administrative terms only
3101
- - Additional premium or credit shown on the endorsement
3102
- - Named parties: additional insureds, loss payees, certificate holders, mortgagees
3189
+ For EACH endorsement, extract:
3190
+ - formNumber: the form identifier (e.g. "CG 21 47") \u2014 REQUIRED
3191
+ - editionDate: the edition date if present (e.g. "12 07")
3192
+ - title: endorsement title \u2014 REQUIRED
3193
+ - endorsementType: classify as one of: additional_insured, waiver_of_subrogation, primary_noncontributory, blanket_additional_insured, loss_payee, mortgage_holder, broadening, restriction, exclusion, amendatory, notice_of_cancellation, designated_premises, classification_change, schedule_update, deductible_change, limit_change, territorial_extension, other
3194
+ - effectiveDate: endorsement effective date if shown
3195
+ - affectedCoverageParts: which coverage parts are modified
3196
+ - namedParties: for each party, extract name, role (additional_insured, loss_payee, mortgage_holder, certificate_holder, waiver_beneficiary, designated_person, other), relationship, and scope
3197
+ - keyTerms: notable provisions or key terms
3198
+ - premiumImpact: additional premium or credit if shown
3199
+ - content: full verbatim text \u2014 REQUIRED
3200
+ - pageStart: page number where endorsement begins \u2014 REQUIRED
3201
+ - pageEnd: page number where endorsement ends
3103
3202
 
3104
3203
  PERSONAL LINES ENDORSEMENT RECOGNITION:
3105
3204
  - HO 04 XX series: homeowners endorsements
@@ -3115,23 +3214,39 @@ var import_zod25 = require("zod");
3115
3214
  var ExclusionsSchema = import_zod25.z.object({
3116
3215
  exclusions: import_zod25.z.array(
3117
3216
  import_zod25.z.object({
3118
- title: import_zod25.z.string().describe("Exclusion title or short description"),
3119
- content: import_zod25.z.string().optional().describe("Full verbatim exclusion text"),
3217
+ name: import_zod25.z.string().describe("Exclusion title or short description"),
3120
3218
  formNumber: import_zod25.z.string().optional().describe("Form number if part of a named endorsement"),
3121
- appliesTo: import_zod25.z.string().optional().describe("Coverage type this exclusion applies to")
3219
+ excludedPerils: import_zod25.z.array(import_zod25.z.string()).optional().describe("Specific perils excluded"),
3220
+ isAbsolute: import_zod25.z.boolean().optional().describe("Whether the exclusion is absolute (no exceptions)"),
3221
+ exceptions: import_zod25.z.array(import_zod25.z.string()).optional().describe("Exceptions to the exclusion, if any"),
3222
+ buybackAvailable: import_zod25.z.boolean().optional().describe("Whether coverage can be bought back via endorsement"),
3223
+ buybackEndorsement: import_zod25.z.string().optional().describe("Form number of the buyback endorsement if available"),
3224
+ appliesTo: import_zod25.z.array(import_zod25.z.string()).optional().describe("Coverage types this exclusion applies to"),
3225
+ content: import_zod25.z.string().describe("Full verbatim exclusion text"),
3226
+ pageNumber: import_zod25.z.number().optional().describe("Page number where exclusion appears")
3122
3227
  })
3123
3228
  ).describe("All exclusions found in the document")
3124
3229
  });
3125
3230
  function buildExclusionsPrompt() {
3126
3231
  return `You are an expert insurance document analyst. Extract ALL exclusions from this document. Preserve original language verbatim.
3127
3232
 
3233
+ For EACH exclusion, extract:
3234
+ - name: exclusion title or short description \u2014 REQUIRED
3235
+ - formNumber: form number if the exclusion is part of a named endorsement
3236
+ - excludedPerils: specific perils being excluded
3237
+ - isAbsolute: true if the exclusion has no exceptions, false if exceptions exist
3238
+ - exceptions: any exceptions to the exclusion (things still covered despite the exclusion)
3239
+ - buybackAvailable: whether coverage can be purchased back via endorsement
3240
+ - buybackEndorsement: the form number of the buyback endorsement if known
3241
+ - appliesTo: which coverage types or lines this exclusion applies to (as an array)
3242
+ - content: full verbatim exclusion text \u2014 REQUIRED
3243
+ - pageNumber: page number where the exclusion appears
3244
+
3128
3245
  Focus on:
3129
3246
  - Named exclusions from exclusion schedules
3130
3247
  - Exclusions embedded within endorsements
3131
3248
  - Exclusions within insuring agreements or conditions if clearly labeled
3132
3249
  - Full verbatim exclusion text \u2014 do not summarize
3133
- - Form number if the exclusion is part of a named endorsement
3134
- - Which coverage line the exclusion applies to, if specific
3135
3250
 
3136
3251
  Common personal lines exclusion patterns: animal liability, business pursuits, home daycare, watercraft, aircraft.
3137
3252
 
@@ -3143,43 +3258,62 @@ var import_zod26 = require("zod");
3143
3258
  var ConditionsSchema = import_zod26.z.object({
3144
3259
  conditions: import_zod26.z.array(
3145
3260
  import_zod26.z.object({
3146
- type: import_zod26.z.enum([
3261
+ name: import_zod26.z.string().describe("Condition title"),
3262
+ conditionType: import_zod26.z.enum([
3147
3263
  "duties_after_loss",
3148
- "cooperation",
3264
+ "notice_requirements",
3265
+ "other_insurance",
3149
3266
  "cancellation",
3150
3267
  "nonrenewal",
3151
- "subrogation",
3152
- "other_insurance",
3153
3268
  "transfer_of_rights",
3154
- "examination_under_oath",
3155
- "arbitration",
3156
- "suit_against_us",
3157
3269
  "liberalization",
3270
+ "arbitration",
3271
+ "concealment_fraud",
3272
+ "examination_under_oath",
3273
+ "legal_action",
3274
+ "loss_payment",
3275
+ "appraisal",
3276
+ "mortgage_holders",
3277
+ "policy_territory",
3278
+ "separation_of_insureds",
3158
3279
  "other"
3159
- ]).optional().describe("Condition category"),
3160
- title: import_zod26.z.string().describe("Condition title"),
3161
- content: import_zod26.z.string().optional().describe("Full verbatim condition text"),
3162
- noticeDays: import_zod26.z.number().optional().describe("Notice period in days if specified (e.g. cancellation notice)")
3280
+ ]).describe("Condition category"),
3281
+ content: import_zod26.z.string().describe("Full verbatim condition text"),
3282
+ keyValues: import_zod26.z.array(
3283
+ import_zod26.z.object({
3284
+ key: import_zod26.z.string().describe("Key name (e.g. 'noticePeriod', 'suitDeadline')"),
3285
+ value: import_zod26.z.string().describe("Value (e.g. '30 days', '2 years')")
3286
+ })
3287
+ ).optional().describe("Key values extracted from the condition (notice periods, deadlines, etc.)"),
3288
+ pageNumber: import_zod26.z.number().optional().describe("Page number where condition appears")
3163
3289
  })
3164
3290
  ).describe("All policy conditions found in the document")
3165
3291
  });
3166
3292
  function buildConditionsPrompt() {
3167
3293
  return `You are an expert insurance document analyst. Extract ALL policy conditions from this document. Preserve original language verbatim.
3168
3294
 
3295
+ For EACH condition, extract:
3296
+ - name: condition title \u2014 REQUIRED
3297
+ - conditionType: classify as one of: duties_after_loss, notice_requirements, other_insurance, cancellation, nonrenewal, transfer_of_rights, liberalization, arbitration, concealment_fraud, examination_under_oath, legal_action, loss_payment, appraisal, mortgage_holders, policy_territory, separation_of_insureds, other \u2014 REQUIRED
3298
+ - content: full verbatim condition text \u2014 REQUIRED
3299
+ - keyValues: extract specific values as key-value pairs (e.g. noticePeriod: "30 days", suitDeadline: "2 years")
3300
+ - pageNumber: page number where the condition appears
3301
+
3169
3302
  Focus on:
3170
3303
  - Duties after loss / notice of occurrence conditions
3171
- - Cooperation clause
3172
- - Cancellation and nonrenewal conditions (extract notice period in days)
3173
- - Subrogation / transfer of rights
3304
+ - Notice requirements (extract notice period as keyValue)
3305
+ - Cancellation and nonrenewal conditions (extract notice period in days as keyValue)
3174
3306
  - Other insurance clause
3307
+ - Subrogation / transfer of rights
3175
3308
  - Examination under oath
3176
3309
  - Arbitration or appraisal provisions
3177
3310
  - Suit against us / legal action conditions
3178
3311
  - Liberalization clause
3312
+ - Concealment or fraud clause
3313
+ - Loss payment conditions
3314
+ - Mortgage holders clause
3179
3315
  - Any other named conditions
3180
3316
 
3181
- For cancellation and nonrenewal conditions, extract the specific notice period in days if stated.
3182
-
3183
3317
  Return JSON only.`;
3184
3318
  }
3185
3319
 
@@ -3460,12 +3594,16 @@ function createExtractor(config) {
3460
3594
  },
3461
3595
  {
3462
3596
  fallback: { documentType: "policy", policyTypes: ["other"], confidence: 0 },
3597
+ maxRetries: 3,
3463
3598
  log,
3464
- onError: (err, attempt) => log?.(`Classify attempt ${attempt + 1} failed: ${err}`)
3599
+ onError: (err, attempt) => log?.(`Classify attempt ${attempt + 1} failed: ${err instanceof Error ? err.message : String(err)}`)
3465
3600
  }
3466
3601
  );
3467
3602
  trackUsage(classifyResponse.usage);
3468
3603
  classifyResult = classifyResponse.object;
3604
+ if (classifyResult.confidence === 0) {
3605
+ 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.`);
3606
+ }
3469
3607
  memory.set("classify", classifyResult);
3470
3608
  await pipelineCtx.save("classify", {
3471
3609
  id,