@claritylabs/cl-sdk 1.0.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/LICENSE +190 -0
- package/README.md +196 -0
- package/dist/index.d.mts +536 -0
- package/dist/index.d.ts +536 -0
- package/dist/index.js +30483 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +30407 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +49 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
import { LanguageModel } from 'ai';
|
|
2
|
+
import { ProviderOptions } from '@ai-sdk/provider-utils';
|
|
3
|
+
import { PDFDocument } from 'pdf-lib';
|
|
4
|
+
|
|
5
|
+
interface Coverage {
|
|
6
|
+
name: string;
|
|
7
|
+
limit: string;
|
|
8
|
+
deductible?: string;
|
|
9
|
+
pageNumber?: number;
|
|
10
|
+
sectionRef?: string;
|
|
11
|
+
}
|
|
12
|
+
interface Subsection {
|
|
13
|
+
title: string;
|
|
14
|
+
sectionNumber?: string;
|
|
15
|
+
pageNumber?: number;
|
|
16
|
+
content: string;
|
|
17
|
+
}
|
|
18
|
+
interface Section {
|
|
19
|
+
title: string;
|
|
20
|
+
sectionNumber?: string;
|
|
21
|
+
pageStart: number;
|
|
22
|
+
pageEnd?: number;
|
|
23
|
+
type: string;
|
|
24
|
+
coverageType?: string;
|
|
25
|
+
content: string;
|
|
26
|
+
subsections?: Subsection[];
|
|
27
|
+
}
|
|
28
|
+
interface Subjectivity {
|
|
29
|
+
description: string;
|
|
30
|
+
category?: string;
|
|
31
|
+
}
|
|
32
|
+
interface UnderwritingCondition {
|
|
33
|
+
description: string;
|
|
34
|
+
}
|
|
35
|
+
interface PremiumLine {
|
|
36
|
+
line: string;
|
|
37
|
+
amount: string;
|
|
38
|
+
}
|
|
39
|
+
interface BaseDocument {
|
|
40
|
+
id: string;
|
|
41
|
+
type: "policy" | "quote";
|
|
42
|
+
carrier: string;
|
|
43
|
+
security?: string;
|
|
44
|
+
insuredName: string;
|
|
45
|
+
premium?: string;
|
|
46
|
+
summary?: string;
|
|
47
|
+
policyTypes?: string[];
|
|
48
|
+
coverages: Coverage[];
|
|
49
|
+
sections?: Section[];
|
|
50
|
+
}
|
|
51
|
+
interface PolicyDocument extends BaseDocument {
|
|
52
|
+
type: "policy";
|
|
53
|
+
policyNumber: string;
|
|
54
|
+
effectiveDate: string;
|
|
55
|
+
expirationDate: string;
|
|
56
|
+
}
|
|
57
|
+
interface QuoteDocument extends BaseDocument {
|
|
58
|
+
type: "quote";
|
|
59
|
+
quoteNumber: string;
|
|
60
|
+
proposedEffectiveDate?: string;
|
|
61
|
+
proposedExpirationDate?: string;
|
|
62
|
+
quoteExpirationDate?: string;
|
|
63
|
+
subjectivities?: Subjectivity[];
|
|
64
|
+
underwritingConditions?: UnderwritingCondition[];
|
|
65
|
+
premiumBreakdown?: PremiumLine[];
|
|
66
|
+
}
|
|
67
|
+
type InsuranceDocument = PolicyDocument | QuoteDocument;
|
|
68
|
+
|
|
69
|
+
type Platform = "email" | "chat" | "sms" | "slack" | "discord";
|
|
70
|
+
type CommunicationIntent = "direct" | "mediated" | "observed";
|
|
71
|
+
interface PlatformConfig {
|
|
72
|
+
supportsMarkdown: boolean;
|
|
73
|
+
supportsLinks: boolean;
|
|
74
|
+
supportsRichFormatting: boolean;
|
|
75
|
+
maxResponseLength?: number;
|
|
76
|
+
signOff?: boolean;
|
|
77
|
+
}
|
|
78
|
+
declare const PLATFORM_CONFIGS: Record<Platform, PlatformConfig>;
|
|
79
|
+
interface AgentContext {
|
|
80
|
+
platform: Platform;
|
|
81
|
+
intent: CommunicationIntent;
|
|
82
|
+
platformConfig?: PlatformConfig;
|
|
83
|
+
companyName?: string;
|
|
84
|
+
companyContext?: string;
|
|
85
|
+
siteUrl: string;
|
|
86
|
+
userName?: string;
|
|
87
|
+
coiHandling?: "broker" | "user" | "member" | "ignore";
|
|
88
|
+
brokerName?: string;
|
|
89
|
+
brokerContactName?: string;
|
|
90
|
+
brokerContactEmail?: string;
|
|
91
|
+
/** Display name for the AI agent. Defaults to "CL-0 Agent" if not set. */
|
|
92
|
+
agentName?: string;
|
|
93
|
+
/** Custom link guidance for the AI. Replaces the default policy/quote link examples.
|
|
94
|
+
* Should include markdown link examples showing the AI how to format document links.
|
|
95
|
+
* Only used when the platform supports links and intent is "direct". */
|
|
96
|
+
linkGuidance?: string;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
interface ModelConfig {
|
|
100
|
+
/** Pass 0: document type classification (fast, cheap model) */
|
|
101
|
+
classification: LanguageModel;
|
|
102
|
+
/** Pass 1: metadata extraction (capable model) */
|
|
103
|
+
metadata: LanguageModel;
|
|
104
|
+
/** Pass 2: chunked section extraction (fast, cheap model) */
|
|
105
|
+
sections: LanguageModel;
|
|
106
|
+
/** Pass 2 fallback when sections model truncates */
|
|
107
|
+
sectionsFallback: LanguageModel;
|
|
108
|
+
/** Pass 3: supplementary field enrichment (fast, cheap model) */
|
|
109
|
+
enrichment: LanguageModel;
|
|
110
|
+
}
|
|
111
|
+
/** Create a ModelConfig where every role uses the same model. */
|
|
112
|
+
declare function createUniformModelConfig(model: LanguageModel): ModelConfig;
|
|
113
|
+
/** Token limits per role — determined by the task, not the provider. */
|
|
114
|
+
declare const MODEL_TOKEN_LIMITS: {
|
|
115
|
+
readonly classification: 512;
|
|
116
|
+
readonly metadata: 4096;
|
|
117
|
+
readonly sections: 8192;
|
|
118
|
+
readonly sectionsFallback: 16384;
|
|
119
|
+
readonly enrichment: 4096;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Create a ModelConfig using the default Anthropic models.
|
|
123
|
+
*
|
|
124
|
+
* Requires `@ai-sdk/anthropic` to be installed — lazy-imported so consumers
|
|
125
|
+
* who bring their own provider never need it.
|
|
126
|
+
*/
|
|
127
|
+
declare function createDefaultModelConfig(): ModelConfig;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Extraction prompt for insurance policy documents.
|
|
131
|
+
* Single source of truth — used by extractPolicy, retryExtraction, and reExtractFromFile.
|
|
132
|
+
*/
|
|
133
|
+
/**
|
|
134
|
+
* @deprecated No longer used for new extractions. Kept for backward compatibility
|
|
135
|
+
* with rawExtractionResponse reparse (older extractions may have used this format).
|
|
136
|
+
* New extractions use two-pass flow: METADATA_PROMPT (Sonnet) + buildSectionsPrompt (Haiku).
|
|
137
|
+
*/
|
|
138
|
+
declare const EXTRACTION_PROMPT = "You are an expert insurance document analyst. Extract comprehensive structured data from this insurance document. Preserve original language verbatim \u2014 do not summarize or paraphrase section content.\n\nRespond with JSON only. The JSON must follow this exact structure:\n\n{\n \"metadata\": {\n \"carrier\": \"primary insurance company name (for display purposes)\",\n \"security\": \"insurer or underwriter entity providing coverage, e.g. 'Lloyd's Underwriters' \u2014 the legal entity on risk\",\n \"underwriter\": \"named individual underwriter if listed, or null\",\n \"mga\": \"Managing General Agent or Program Administrator name if applicable (e.g. 'CFC Underwriting'), or null\",\n \"broker\": \"insurance broker name if identifiable, or null\",\n \"policyNumber\": \"policy or quote reference number\",\n \"documentType\": \"policy\" or \"quote\",\n \"policyTypes\": [\"general_liability\", \"workers_comp\", \"commercial_auto\", \"non_owned_auto\", \"property\", \"umbrella\", \"professional_liability\", \"cyber\", \"epli\", \"directors_officers\", \"other\"],\n \"policyYear\": number,\n \"effectiveDate\": \"MM/DD/YYYY\",\n \"expirationDate\": \"MM/DD/YYYY\",\n \"isRenewal\": boolean,\n \"premium\": \"$X,XXX\",\n \"insuredName\": \"name of insured party\",\n \"summary\": \"1-2 sentence summary of the document\"\n },\n \"metadataSource\": {\n \"carrierPage\": number or null,\n \"policyNumberPage\": number or null,\n \"premiumPage\": number or null,\n \"effectiveDatePage\": number or null\n },\n \"coverages\": [\n {\n \"name\": \"coverage name\",\n \"limit\": \"$X,XXX,XXX\",\n \"deductible\": \"$X,XXX or null\",\n \"pageNumber\": number,\n \"sectionRef\": \"section number reference or null\"\n }\n ],\n \"document\": {\n \"sections\": [\n {\n \"title\": \"section title\",\n \"sectionNumber\": \"e.g. 'I', '1.1', 'A' \u2014 or null if unnumbered\",\n \"pageStart\": number,\n \"pageEnd\": number or null,\n \"type\": \"one of: declarations, insuring_agreement, exclusion, condition, definition, endorsement, schedule, subjectivity, warranty, notice, regulatory, other\",\n \"coverageType\": \"links to policyTypes value if section is coverage-specific, or null\",\n \"content\": \"full verbatim text of the section\",\n \"subsections\": [\n {\n \"title\": \"subsection title\",\n \"sectionNumber\": \"subsection number or null\",\n \"pageNumber\": number or null,\n \"content\": \"full verbatim text\"\n }\n ]\n }\n ],\n \"regulatoryContext\": {\n \"content\": \"all regulatory context, governing law, jurisdiction clauses \u2014 verbatim\",\n \"pageNumber\": number\n },\n \"complaintContact\": {\n \"content\": \"complaint contact information and instructions \u2014 verbatim\",\n \"pageNumber\": number\n },\n \"costsAndFees\": {\n \"content\": \"other costs, fees, surcharges, and charges \u2014 verbatim\",\n \"pageNumber\": number\n }\n },\n \"totalPages\": number\n}\n\nIMPORTANT INSTRUCTIONS:\n- policyTypes should include ALL coverage types found in the document\n- documentType should be \"quote\" if this is a quote/proposal, \"policy\" if it is a bound policy\n- For carrier, use the primary company name. For security, use the full legal entity providing coverage\n- Extract EVERY section, clause, endorsement, and schedule from the document as a separate entry in document.sections\n- Preserve the original language exactly as written in the document \u2014 do not summarize\n- Include accurate page numbers for every section and data point\n- Classify each section by type (declarations, insuring_agreement, exclusion, condition, etc.)\n- If a section relates to a specific coverage type, set coverageType to match the policyTypes value\n- For regulatoryContext, complaintContact, and costsAndFees: set to null if not found in the document\n- subsections within a section are optional \u2014 only include if the section has clearly defined subsections";
|
|
139
|
+
/**
|
|
140
|
+
* Pass 0: Document classification prompt (Haiku).
|
|
141
|
+
* Quick classification to determine if a document is a policy or a quote.
|
|
142
|
+
*/
|
|
143
|
+
declare const CLASSIFY_DOCUMENT_PROMPT = "You are an expert insurance document analyst. Classify this document as either a bound insurance POLICY or a QUOTE/PROPOSAL.\n\nRespond with JSON only:\n\n{\n \"documentType\": \"policy\" or \"quote\",\n \"confidence\": number between 0 and 1,\n \"signals\": [\"signal 1\", \"signal 2\"]\n}\n\nCLASSIFICATION SIGNALS:\n- POLICY signals: declarations page, ISO form numbers (e.g. CG 00 01), binding language (\"This policy is issued to\"), endorsement schedules, \"Certificate of Insurance\"\n- QUOTE signals: \"quote\", \"proposal\", \"indication\" wording, subjectivities, \"subject to\" conditions, quote expiration date, \"proposed premium\", \"terms and conditions may vary\"\n\nIf uncertain, lean toward \"policy\" for documents with declarations pages and binding language, \"quote\" for everything else.";
|
|
144
|
+
/**
|
|
145
|
+
* Chunked extraction: metadata-only prompt for the first pass on long documents.
|
|
146
|
+
* Used for both policy and quote extractions (documentType already known from pass 0).
|
|
147
|
+
*/
|
|
148
|
+
declare const METADATA_PROMPT = "You are an expert insurance document analyst. Extract ONLY the high-level metadata from this insurance document. Do NOT extract full section content \u2014 that will be done in a separate pass.\n\nRespond with JSON only:\n\n{\n \"metadata\": {\n \"carrier\": \"primary insurance company name\",\n \"security\": \"insurer or underwriter entity providing coverage, or null\",\n \"underwriter\": \"named individual underwriter, or null\",\n \"mga\": \"MGA or Program Administrator, or null\",\n \"broker\": \"insurance broker, or null\",\n \"policyNumber\": \"policy number\",\n \"documentType\": \"policy\" or \"quote\",\n \"policyTypes\": [\"general_liability\", ...],\n \"policyYear\": number,\n \"effectiveDate\": \"MM/DD/YYYY\",\n \"expirationDate\": \"MM/DD/YYYY\",\n \"isRenewal\": boolean,\n \"premium\": \"$X,XXX\",\n \"insuredName\": \"name of insured party\",\n \"summary\": \"1-2 sentence summary\"\n },\n \"metadataSource\": {\n \"carrierPage\": number or null,\n \"policyNumberPage\": number or null,\n \"premiumPage\": number or null,\n \"effectiveDatePage\": number or null\n },\n \"coverages\": [\n { \"name\": \"coverage name\", \"limit\": \"$X,XXX,XXX\", \"deductible\": \"$X,XXX or null\", \"pageNumber\": number, \"sectionRef\": \"section ref or null\" }\n ],\n \"totalPages\": number,\n \"tableOfContents\": [\n { \"title\": \"section title\", \"pageStart\": number, \"pageEnd\": number }\n ]\n}";
|
|
149
|
+
/**
|
|
150
|
+
* Quote-specific metadata prompt (Sonnet).
|
|
151
|
+
* Extracts quote-specific fields like subjectivities, underwriting conditions, premium breakdown.
|
|
152
|
+
*/
|
|
153
|
+
declare const QUOTE_METADATA_PROMPT = "You are an expert insurance document analyst. Extract ONLY the high-level metadata from this insurance QUOTE or PROPOSAL document. Do NOT extract full section content \u2014 that will be done in a separate pass.\n\nRespond with JSON only:\n\n{\n \"metadata\": {\n \"carrier\": \"primary insurance company name\",\n \"security\": \"insurer or underwriter entity providing coverage, or null\",\n \"underwriter\": \"named individual underwriter, or null\",\n \"mga\": \"MGA or Program Administrator, or null\",\n \"broker\": \"insurance broker, or null\",\n \"quoteNumber\": \"quote or proposal reference number\",\n \"policyTypes\": [\"general_liability\", ...],\n \"quoteYear\": number,\n \"proposedEffectiveDate\": \"MM/DD/YYYY or null\",\n \"proposedExpirationDate\": \"MM/DD/YYYY or null\",\n \"quoteExpirationDate\": \"MM/DD/YYYY \u2014 when this quote offer expires, or null\",\n \"isRenewal\": boolean,\n \"premium\": \"$X,XXX \u2014 total proposed premium\",\n \"insuredName\": \"name of insured party\",\n \"summary\": \"1-2 sentence summary of the quote\"\n },\n \"metadataSource\": {\n \"carrierPage\": number or null,\n \"quoteNumberPage\": number or null,\n \"premiumPage\": number or null,\n \"effectiveDatePage\": number or null\n },\n \"coverages\": [\n { \"name\": \"coverage name\", \"proposedLimit\": \"$X,XXX,XXX\", \"proposedDeductible\": \"$X,XXX or null\", \"pageNumber\": number, \"sectionRef\": \"section ref or null\" }\n ],\n \"premiumBreakdown\": [\n { \"line\": \"coverage line name\", \"amount\": \"$X,XXX\" }\n ],\n \"subjectivities\": [\n { \"description\": \"subjectivity description\", \"category\": \"pre_binding\" or \"post_binding\" or \"information\" or null, \"pageNumber\": number or null }\n ],\n \"underwritingConditions\": [\n { \"description\": \"condition description\", \"pageNumber\": number or null }\n ],\n \"totalPages\": number,\n \"tableOfContents\": [\n { \"title\": \"section title\", \"pageStart\": number, \"pageEnd\": number }\n ]\n}\n\nIMPORTANT:\n- quoteExpirationDate is when the quote offer itself expires (not the proposed policy period)\n- subjectivities are conditions that must be met before or after binding (look for \"subject to\", \"subjectivities\", \"conditions precedent\")\n- premiumBreakdown should list each coverage line's individual premium if available";
|
|
154
|
+
/**
|
|
155
|
+
* Chunked extraction: sections prompt for a specific page range (policies).
|
|
156
|
+
*/
|
|
157
|
+
declare function buildSectionsPrompt(pageStart: number, pageEnd: number): string;
|
|
158
|
+
/** Alias for backward compatibility */
|
|
159
|
+
declare const buildPolicySectionsPrompt: typeof buildSectionsPrompt;
|
|
160
|
+
/**
|
|
161
|
+
* Chunked extraction: sections prompt for quote documents.
|
|
162
|
+
*/
|
|
163
|
+
declare function buildQuoteSectionsPrompt(pageStart: number, pageEnd: number): string;
|
|
164
|
+
/**
|
|
165
|
+
* Pass 3: Supplementary field enrichment prompt.
|
|
166
|
+
* Text-only (no PDF) — parses raw text blobs into structured data.
|
|
167
|
+
*/
|
|
168
|
+
declare function buildSupplementaryEnrichmentPrompt(fields: {
|
|
169
|
+
regulatoryContext?: string;
|
|
170
|
+
complaintContact?: string;
|
|
171
|
+
costsAndFees?: string;
|
|
172
|
+
claimsContact?: string;
|
|
173
|
+
}): string;
|
|
174
|
+
|
|
175
|
+
declare const APPLICATION_CLASSIFY_PROMPT = "You are classifying a PDF document. Determine if this is an insurance APPLICATION FORM (a form to be filled out to apply for insurance) versus a policy document, quote, certificate, or other document.\n\nInsurance applications typically:\n- Have blank fields, checkboxes, or spaces to fill in\n- Ask for company information, coverage limits, loss history\n- Include ACORD form numbers or \"Application for\" in the title\n- Request signatures and dates\n\nRespond with JSON only:\n{\n \"isApplication\": boolean,\n \"confidence\": number (0-1),\n \"applicationType\": string | null // e.g. \"General Liability\", \"Professional Liability\", \"Commercial Property\", \"Workers Compensation\", \"ACORD 125\", etc.\n}";
|
|
176
|
+
declare function buildFieldExtractionPrompt(): string;
|
|
177
|
+
declare function buildAutoFillPrompt(fields: {
|
|
178
|
+
id: string;
|
|
179
|
+
label: string;
|
|
180
|
+
fieldType: string;
|
|
181
|
+
section: string;
|
|
182
|
+
}[], orgContext: {
|
|
183
|
+
key: string;
|
|
184
|
+
value: string;
|
|
185
|
+
category: string;
|
|
186
|
+
}[]): string;
|
|
187
|
+
declare function buildQuestionBatchPrompt(unfilledFields: {
|
|
188
|
+
id: string;
|
|
189
|
+
label?: string;
|
|
190
|
+
text?: string;
|
|
191
|
+
fieldType: string;
|
|
192
|
+
section: string;
|
|
193
|
+
required: boolean;
|
|
194
|
+
condition?: {
|
|
195
|
+
dependsOn: string;
|
|
196
|
+
whenValue: string;
|
|
197
|
+
};
|
|
198
|
+
}[]): string;
|
|
199
|
+
declare function buildAnswerParsingPrompt(questions: {
|
|
200
|
+
id: string;
|
|
201
|
+
label?: string;
|
|
202
|
+
text?: string;
|
|
203
|
+
fieldType: string;
|
|
204
|
+
}[], emailBody: string): string;
|
|
205
|
+
declare function buildConfirmationSummaryPrompt(fields: {
|
|
206
|
+
id: string;
|
|
207
|
+
label?: string;
|
|
208
|
+
text?: string;
|
|
209
|
+
section: string;
|
|
210
|
+
fieldType: string;
|
|
211
|
+
value?: string;
|
|
212
|
+
}[], applicationTitle: string): string;
|
|
213
|
+
declare function buildBatchEmailGenerationPrompt(batchFields: {
|
|
214
|
+
id: string;
|
|
215
|
+
label: string;
|
|
216
|
+
fieldType: string;
|
|
217
|
+
options?: string[];
|
|
218
|
+
condition?: {
|
|
219
|
+
dependsOn: string;
|
|
220
|
+
whenValue: string;
|
|
221
|
+
};
|
|
222
|
+
}[], batchIndex: number, totalBatches: number, appTitle: string | undefined, totalFieldCount: number, filledFieldCount: number, previousBatchSummary?: string, companyName?: string): string;
|
|
223
|
+
declare function buildReplyIntentClassificationPrompt(questions: {
|
|
224
|
+
id: string;
|
|
225
|
+
label: string;
|
|
226
|
+
}[], emailBody: string): string;
|
|
227
|
+
declare function buildFieldExplanationPrompt(field: {
|
|
228
|
+
id: string;
|
|
229
|
+
label: string;
|
|
230
|
+
fieldType: string;
|
|
231
|
+
options?: string[];
|
|
232
|
+
}, question: string, policyContext?: string): string;
|
|
233
|
+
declare function buildFlatPdfMappingPrompt(extractedFields: {
|
|
234
|
+
id: string;
|
|
235
|
+
label: string;
|
|
236
|
+
value: string;
|
|
237
|
+
fieldType: string;
|
|
238
|
+
}[]): string;
|
|
239
|
+
declare function buildAcroFormMappingPrompt(extractedFields: {
|
|
240
|
+
id: string;
|
|
241
|
+
label: string;
|
|
242
|
+
value?: string;
|
|
243
|
+
}[], acroFormFields: {
|
|
244
|
+
name: string;
|
|
245
|
+
type: string;
|
|
246
|
+
options?: string[];
|
|
247
|
+
}[]): string;
|
|
248
|
+
declare function buildLookupFillPrompt(requests: {
|
|
249
|
+
type: string;
|
|
250
|
+
description: string;
|
|
251
|
+
targetFieldIds: string[];
|
|
252
|
+
}[], targetFields: {
|
|
253
|
+
id: string;
|
|
254
|
+
label: string;
|
|
255
|
+
fieldType: string;
|
|
256
|
+
}[], availableData: string): string;
|
|
257
|
+
|
|
258
|
+
declare function buildIdentityPrompt(ctx: AgentContext): string;
|
|
259
|
+
|
|
260
|
+
declare function buildSafetyPrompt(ctx: AgentContext): string;
|
|
261
|
+
|
|
262
|
+
declare function buildFormattingPrompt(ctx: AgentContext): string;
|
|
263
|
+
|
|
264
|
+
declare function buildCoverageGapPrompt(ctx: AgentContext): string | null;
|
|
265
|
+
|
|
266
|
+
declare function buildCoiRoutingPrompt(ctx: AgentContext): string | null;
|
|
267
|
+
|
|
268
|
+
declare function buildQuotesPoliciesPrompt(): string;
|
|
269
|
+
|
|
270
|
+
declare function buildConversationMemoryGuidance(): string;
|
|
271
|
+
|
|
272
|
+
declare function buildIntentPrompt(ctx: AgentContext): string;
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Build a complete agent system prompt from composable modules.
|
|
276
|
+
*
|
|
277
|
+
* Composes: identity -> company context -> intent -> formatting -> safety
|
|
278
|
+
* -> coverage gaps -> COI routing -> quotes/policies -> memory guidance.
|
|
279
|
+
*
|
|
280
|
+
* Modules that return null (e.g. coverage gaps in direct mode) are filtered out.
|
|
281
|
+
*/
|
|
282
|
+
declare function buildAgentSystemPrompt(ctx: AgentContext): string;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* @deprecated Use `buildAgentSystemPrompt` from `prompts/agent/index` instead.
|
|
286
|
+
* Maps legacy mode strings to the new platform/intent API.
|
|
287
|
+
*/
|
|
288
|
+
declare function buildSystemPrompt(mode: "direct" | "cc" | "forward", companyContext: string | undefined, siteUrl: string, companyName?: string, userName?: string, coiHandling?: "broker" | "user" | "member" | "ignore", brokerName?: string, brokerContactName?: string, brokerContactEmail?: string): string;
|
|
289
|
+
/** @deprecated Use buildDocumentContext instead */
|
|
290
|
+
declare function buildPolicyContext(policies: PolicyDocument[], queryText: string): {
|
|
291
|
+
context: string;
|
|
292
|
+
relevantPolicyIds: string[];
|
|
293
|
+
};
|
|
294
|
+
declare function buildDocumentContext(policies: PolicyDocument[], quotes: QuoteDocument[], queryText: string): {
|
|
295
|
+
context: string;
|
|
296
|
+
relevantPolicyIds: string[];
|
|
297
|
+
relevantQuoteIds: string[];
|
|
298
|
+
};
|
|
299
|
+
interface PastConversation {
|
|
300
|
+
fromName?: string;
|
|
301
|
+
fromEmail: string;
|
|
302
|
+
subject: string;
|
|
303
|
+
body: string;
|
|
304
|
+
responseBody: string;
|
|
305
|
+
_creationTime: number;
|
|
306
|
+
threadId?: string;
|
|
307
|
+
}
|
|
308
|
+
declare function buildConversationMemoryContext(conversations: PastConversation[]): string;
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Build a platform-agnostic message classification prompt.
|
|
312
|
+
*
|
|
313
|
+
* The prompt instructs Claude to classify an incoming message and suggest
|
|
314
|
+
* an intent, with platform-specific context fields included in the schema.
|
|
315
|
+
*/
|
|
316
|
+
declare function buildClassifyMessagePrompt(platform: Platform): string;
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* @deprecated Use `buildClassifyMessagePrompt("email")` from `prompts/intent` instead.
|
|
320
|
+
*/
|
|
321
|
+
declare const CLASSIFY_EMAIL_PROMPT = "You are an AI assistant that classifies emails. Determine if this email is related to insurance policies (new policies, renewals, certificates of insurance, policy documents, endorsements, binders, premium notices, etc).\n\nRespond with JSON only:\n{\n \"isInsurance\": boolean,\n \"reason\": \"brief explanation\",\n \"confidence\": number between 0 and 1\n}\n\nEmail subject: {{subject}}\nFrom: {{from}}\nDate: {{date}}";
|
|
322
|
+
|
|
323
|
+
interface ToolDefinition {
|
|
324
|
+
name: string;
|
|
325
|
+
description: string;
|
|
326
|
+
input_schema: {
|
|
327
|
+
type: "object";
|
|
328
|
+
properties: Record<string, unknown>;
|
|
329
|
+
required?: string[];
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
declare const DOCUMENT_LOOKUP_TOOL: ToolDefinition;
|
|
333
|
+
declare const COI_GENERATION_TOOL: ToolDefinition;
|
|
334
|
+
declare const COVERAGE_COMPARISON_TOOL: ToolDefinition;
|
|
335
|
+
declare const AGENT_TOOLS: ToolDefinition[];
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Multi-pass extraction pipeline for insurance PDFs.
|
|
339
|
+
*
|
|
340
|
+
* Processes documents in up to 4 passes with adaptive fallback:
|
|
341
|
+
*
|
|
342
|
+
* - **Pass 0 (Classification)**: Classification model classifies document as policy or quote.
|
|
343
|
+
* - **Pass 1 (Metadata)**: Metadata model extracts high-level metadata (carrier, dates,
|
|
344
|
+
* premium, coverages). Supports `onMetadata?()` callback for early persistence
|
|
345
|
+
* so metadata survives pass 2 failures.
|
|
346
|
+
* - **Pass 2 (Sections)**: Chunked extraction with sections model. Documents are split into
|
|
347
|
+
* 15-page chunks; on JSON parse failure (usually output truncation), re-splits
|
|
348
|
+
* to 10 -> 5 pages, then falls back to sectionsFallback model. `mergeChunkedSections()` combines.
|
|
349
|
+
* - **Pass 3 (Enrichment)**: Enrichment model enriches supplementary fields (regulatory context,
|
|
350
|
+
* contacts) from raw text. Non-fatal on failure.
|
|
351
|
+
*
|
|
352
|
+
* Separate entry points exist for policies (`extractFromPdf`) vs quotes
|
|
353
|
+
* (`extractQuoteFromPdf`). `extractSectionsOnly()` retries pass 2 using
|
|
354
|
+
* saved metadata from a prior pass 1.
|
|
355
|
+
*
|
|
356
|
+
* Provider-agnostic: accepts `ModelConfig` with Vercel AI SDK `LanguageModel` instances.
|
|
357
|
+
* Defaults to Anthropic models via `createDefaultModelConfig()`.
|
|
358
|
+
*/
|
|
359
|
+
|
|
360
|
+
declare const SONNET_MODEL = "claude-sonnet-4-6";
|
|
361
|
+
declare const HAIKU_MODEL = "claude-haiku-4-5-20251001";
|
|
362
|
+
type LogFn = (message: string) => Promise<void>;
|
|
363
|
+
/** Strip markdown code fences from AI response text. */
|
|
364
|
+
declare function stripFences(text: string): string;
|
|
365
|
+
/**
|
|
366
|
+
* Recursively convert null values to undefined.
|
|
367
|
+
*
|
|
368
|
+
* Required because Convex rejects `null` for optional fields, but Claude
|
|
369
|
+
* routinely returns `null` for missing values in JSON output. Applied to
|
|
370
|
+
* all extraction results before persistence.
|
|
371
|
+
*/
|
|
372
|
+
declare function sanitizeNulls<T>(obj: T): T;
|
|
373
|
+
/** Map raw Claude extraction JSON to mutation-compatible fields. */
|
|
374
|
+
declare function applyExtracted(extracted: any): {
|
|
375
|
+
carrier: any;
|
|
376
|
+
security: any;
|
|
377
|
+
underwriter: any;
|
|
378
|
+
mga: any;
|
|
379
|
+
broker: any;
|
|
380
|
+
policyNumber: any;
|
|
381
|
+
policyTypes: any;
|
|
382
|
+
documentType: "policy" | "quote";
|
|
383
|
+
policyYear: any;
|
|
384
|
+
effectiveDate: any;
|
|
385
|
+
expirationDate: any;
|
|
386
|
+
isRenewal: any;
|
|
387
|
+
coverages: any;
|
|
388
|
+
premium: any;
|
|
389
|
+
insuredName: any;
|
|
390
|
+
summary: any;
|
|
391
|
+
metadataSource: any;
|
|
392
|
+
document: any;
|
|
393
|
+
extractionStatus: "complete";
|
|
394
|
+
extractionError: string;
|
|
395
|
+
};
|
|
396
|
+
/**
|
|
397
|
+
* Merge document sections from chunked extraction passes.
|
|
398
|
+
*
|
|
399
|
+
* Combines sections from all chunks into a single array and takes the last
|
|
400
|
+
* non-null value for supplementary fields (regulatoryContext, complaintContact,
|
|
401
|
+
* costsAndFees, claimsContact) since these typically appear only once.
|
|
402
|
+
*/
|
|
403
|
+
declare function mergeChunkedSections(metadataResult: any, sectionChunks: any[]): any;
|
|
404
|
+
/** Determine page ranges for chunked extraction. */
|
|
405
|
+
declare function getPageChunks(totalPages: number, chunkSize?: number): Array<[number, number]>;
|
|
406
|
+
/**
|
|
407
|
+
* Pass 3: Enrich supplementary fields with structured data.
|
|
408
|
+
* Text-only enrichment call — non-fatal on failure (returns document unchanged).
|
|
409
|
+
*/
|
|
410
|
+
declare function enrichSupplementaryFields(document: any, models?: ModelConfig, log?: LogFn): Promise<any>;
|
|
411
|
+
interface ClassifyOptions {
|
|
412
|
+
log?: LogFn;
|
|
413
|
+
models?: ModelConfig;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Pass 0: Classify document as policy or quote.
|
|
417
|
+
*/
|
|
418
|
+
declare function classifyDocumentType(pdfBase64: string, options?: ClassifyOptions): Promise<{
|
|
419
|
+
documentType: "policy" | "quote";
|
|
420
|
+
confidence: number;
|
|
421
|
+
signals: string[];
|
|
422
|
+
}>;
|
|
423
|
+
/** Map raw Claude quote extraction JSON to mutation-compatible fields. */
|
|
424
|
+
declare function applyExtractedQuote(extracted: any): {
|
|
425
|
+
carrier: any;
|
|
426
|
+
security: any;
|
|
427
|
+
underwriter: any;
|
|
428
|
+
mga: any;
|
|
429
|
+
broker: any;
|
|
430
|
+
quoteNumber: any;
|
|
431
|
+
policyTypes: any;
|
|
432
|
+
quoteYear: any;
|
|
433
|
+
proposedEffectiveDate: any;
|
|
434
|
+
proposedExpirationDate: any;
|
|
435
|
+
quoteExpirationDate: any;
|
|
436
|
+
isRenewal: any;
|
|
437
|
+
coverages: any;
|
|
438
|
+
premium: any;
|
|
439
|
+
premiumBreakdown: any;
|
|
440
|
+
insuredName: any;
|
|
441
|
+
summary: any;
|
|
442
|
+
subjectivities: any;
|
|
443
|
+
underwritingConditions: any;
|
|
444
|
+
metadataSource: any;
|
|
445
|
+
document: any;
|
|
446
|
+
extractionStatus: "complete";
|
|
447
|
+
extractionError: string;
|
|
448
|
+
};
|
|
449
|
+
/**
|
|
450
|
+
* Merge document sections from chunked quote extraction passes.
|
|
451
|
+
*
|
|
452
|
+
* Similar to `mergeChunkedSections` but also accumulates quote-specific
|
|
453
|
+
* fields: subjectivities and underwriting conditions from all chunks.
|
|
454
|
+
*/
|
|
455
|
+
declare function mergeChunkedQuoteSections(metadataResult: any, sectionChunks: any[]): any;
|
|
456
|
+
type PromptBuilder = (pageStart: number, pageEnd: number) => string;
|
|
457
|
+
interface ExtractOptions {
|
|
458
|
+
log?: LogFn;
|
|
459
|
+
onMetadata?: (raw: string) => Promise<void>;
|
|
460
|
+
models?: ModelConfig;
|
|
461
|
+
/** Provider-specific options for metadata calls (e.g. Anthropic thinking). Defaults to Anthropic thinking enabled. */
|
|
462
|
+
metadataProviderOptions?: ProviderOptions;
|
|
463
|
+
/** Provider-specific options for fallback calls. Defaults to Anthropic thinking enabled. */
|
|
464
|
+
fallbackProviderOptions?: ProviderOptions;
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Full extraction pipeline for policy documents (passes 1-3).
|
|
468
|
+
*
|
|
469
|
+
* - **Pass 1**: Metadata model extracts metadata, coverages, and page count.
|
|
470
|
+
* - **Pass 2**: Sections model extracts sections in chunks (with adaptive retry and fallback).
|
|
471
|
+
* - **Pass 3**: Enrichment model enriches supplementary fields (non-fatal).
|
|
472
|
+
*
|
|
473
|
+
* @param pdfBase64 - Base64-encoded PDF document.
|
|
474
|
+
* @param options - Extraction options (models, logging, callbacks, provider options).
|
|
475
|
+
*/
|
|
476
|
+
declare function extractFromPdf(pdfBase64: string, options?: ExtractOptions): Promise<{
|
|
477
|
+
rawText: string;
|
|
478
|
+
extracted: any;
|
|
479
|
+
}>;
|
|
480
|
+
interface ExtractSectionsOptions {
|
|
481
|
+
log?: LogFn;
|
|
482
|
+
promptBuilder?: PromptBuilder;
|
|
483
|
+
models?: ModelConfig;
|
|
484
|
+
/** Provider-specific options for fallback calls. */
|
|
485
|
+
fallbackProviderOptions?: ProviderOptions;
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Sections-only extraction: skip pass 1, use saved metadata.
|
|
489
|
+
* For retrying when metadata succeeded but sections failed.
|
|
490
|
+
*/
|
|
491
|
+
declare function extractSectionsOnly(pdfBase64: string, metadataRaw: string, options?: ExtractSectionsOptions): Promise<{
|
|
492
|
+
rawText: string;
|
|
493
|
+
extracted: any;
|
|
494
|
+
}>;
|
|
495
|
+
/**
|
|
496
|
+
* Full extraction pipeline for quote documents (passes 1-2).
|
|
497
|
+
*
|
|
498
|
+
* - **Pass 1**: Metadata model extracts quote-specific metadata (proposed dates,
|
|
499
|
+
* subjectivities, premium breakdown).
|
|
500
|
+
* - **Pass 2**: Sections model extracts sections in chunks (with adaptive retry).
|
|
501
|
+
*
|
|
502
|
+
* Does not run pass 3 enrichment (quotes rarely have supplementary fields).
|
|
503
|
+
*
|
|
504
|
+
* @param pdfBase64 - Base64-encoded PDF document.
|
|
505
|
+
* @param options - Extraction options (models, logging, callbacks, provider options).
|
|
506
|
+
*/
|
|
507
|
+
declare function extractQuoteFromPdf(pdfBase64: string, options?: ExtractOptions): Promise<{
|
|
508
|
+
rawText: string;
|
|
509
|
+
extracted: any;
|
|
510
|
+
}>;
|
|
511
|
+
|
|
512
|
+
interface AcroFormFieldInfo {
|
|
513
|
+
name: string;
|
|
514
|
+
type: "text" | "checkbox" | "dropdown" | "radio";
|
|
515
|
+
options?: string[];
|
|
516
|
+
}
|
|
517
|
+
/** Enumerate all AcroForm fields from a PDF. Returns empty array if no form. */
|
|
518
|
+
declare function getAcroFormFields(pdfDoc: PDFDocument): AcroFormFieldInfo[];
|
|
519
|
+
interface FieldMapping {
|
|
520
|
+
acroFormName: string;
|
|
521
|
+
value: string;
|
|
522
|
+
}
|
|
523
|
+
/** Fill AcroForm fields by mapping, flatten, and return bytes. */
|
|
524
|
+
declare function fillAcroForm(pdfBytes: Uint8Array, mappings: FieldMapping[]): Promise<Uint8Array>;
|
|
525
|
+
interface TextOverlay {
|
|
526
|
+
page: number;
|
|
527
|
+
x: number;
|
|
528
|
+
y: number;
|
|
529
|
+
text: string;
|
|
530
|
+
fontSize?: number;
|
|
531
|
+
isCheckmark?: boolean;
|
|
532
|
+
}
|
|
533
|
+
/** Overlay text on a flat PDF at specified coordinates. */
|
|
534
|
+
declare function overlayTextOnPdf(pdfBytes: Uint8Array, overlays: TextOverlay[]): Promise<Uint8Array>;
|
|
535
|
+
|
|
536
|
+
export { AGENT_TOOLS, APPLICATION_CLASSIFY_PROMPT, type AcroFormFieldInfo, type AgentContext, type BaseDocument, CLASSIFY_DOCUMENT_PROMPT, CLASSIFY_EMAIL_PROMPT, COI_GENERATION_TOOL, COVERAGE_COMPARISON_TOOL, type ClassifyOptions, type CommunicationIntent, type Coverage, DOCUMENT_LOOKUP_TOOL, EXTRACTION_PROMPT, type ExtractOptions, type ExtractSectionsOptions, type FieldMapping, HAIKU_MODEL, type InsuranceDocument, type LogFn, METADATA_PROMPT, MODEL_TOKEN_LIMITS, type ModelConfig, PLATFORM_CONFIGS, type Platform, type PlatformConfig, type PolicyDocument, type PremiumLine, type PromptBuilder, QUOTE_METADATA_PROMPT, type QuoteDocument, SONNET_MODEL, type Section, type Subjectivity, type Subsection, type TextOverlay, type ToolDefinition, type UnderwritingCondition, applyExtracted, applyExtractedQuote, buildAcroFormMappingPrompt, buildAgentSystemPrompt, buildAnswerParsingPrompt, buildAutoFillPrompt, buildBatchEmailGenerationPrompt, buildClassifyMessagePrompt, buildCoiRoutingPrompt, buildConfirmationSummaryPrompt, buildConversationMemoryContext, buildConversationMemoryGuidance, buildCoverageGapPrompt, buildDocumentContext, buildFieldExplanationPrompt, buildFieldExtractionPrompt, buildFlatPdfMappingPrompt, buildFormattingPrompt, buildIdentityPrompt, buildIntentPrompt, buildLookupFillPrompt, buildPolicyContext, buildPolicySectionsPrompt, buildQuestionBatchPrompt, buildQuoteSectionsPrompt, buildQuotesPoliciesPrompt, buildReplyIntentClassificationPrompt, buildSafetyPrompt, buildSectionsPrompt, buildSupplementaryEnrichmentPrompt, buildSystemPrompt, classifyDocumentType, createDefaultModelConfig, createUniformModelConfig, enrichSupplementaryFields, extractFromPdf, extractQuoteFromPdf, extractSectionsOnly, fillAcroForm, getAcroFormFields, getPageChunks, mergeChunkedQuoteSections, mergeChunkedSections, overlayTextOnPdf, sanitizeNulls, stripFences };
|