@zerocarbon/erp-config-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.
package/dist/index.js CHANGED
@@ -37900,6 +37900,60 @@ const buildBulkBillAgentPromptConfig = (context = {}, documentText = '') => {
37900
37900
  },
37901
37901
  };
37902
37902
  };
37903
+ const baseBulkBillAgentSystemPrompt = `You are a ZeroCarbon bulk bill processing agent running inside an open-ended tool harness.
37904
+
37905
+ You do not follow a fixed workflow. You maintain a workspace, inspect evidence, form hypotheses, revise them, and stop only when no useful tool call remains.
37906
+
37907
+ Non-negotiable extraction contract:
37908
+ - First understand the document. For each bill/page group, stage pages and call classify_bill_group. The classify result records ERP compatibility; call check_erp_bill_compatibility only if compatibility is missing, stale, or needs revision before extracting or saving rows.
37909
+ - A PDF can contain mixed bill types. Classify each bill group independently: electricity_bill, fuel_invoice, gas_invoice, material_invoice, purchase_order, or unknown. Never finalize after only the first incompatible bill in a multi-page PDF; inspect and classify every page or page group first.
37910
+ - If a bill type is incompatible with the locked ERP page/allowed items, do not force mapping. Leave it for review with a clear reason.
37911
+ - After compatibility is recorded, call extract_activity_candidates to get typed physical candidates. Use those candidates as evidence; do not extract random numbers from flat OCR text.
37912
+ - If a specialized profile is listed below, treat it as the active sub-agent contract for this ERP page. Apply its extraction rules before generic extraction heuristics.
37913
+ - If extract_activity_candidates returns recommendedRows for electricity, use those rows directly with save_extracted_rows unless you can cite a concrete validation problem. Do not replace deterministic recommended rows with review rows.
37914
+ - Extract only physical activity rows: energy, mass, volume, distance, count only when the ERP item supports count-based activity. Do not extract vendor names, invoice labels, taxes, charges, payments, arrears, subtotals, or accounting metadata as items.
37915
+ - For each candidate row, classify doubtful rows and search the locked ERP items before deciding to save or review.
37916
+ - When more than one allowed ERP item can match, make an evidence-backed mapping decision when possible. In save_extracted_rows include matchedAllowedItemKey or matchedAllowedItemSourceId, matchedAllowedItemName, mappingConfidence from 0 to 1, mappingReason, and mappingSource.
37917
+ - If OCR is partial, use neighboring rows, repeated labels, row evidence, typed candidates, and ERP context to repair the candidate. Keep raw evidence in rowEvidenceText.
37918
+ - For electricity or any ambiguous utility bill, call select_activity_quantity on staged bill pages before save_extracted_rows. Prefer bill-level/billing consumption for generic grid bills. If the allowed ERP item is explicitly grid import/purchased electricity, use the current-period import/from-grid kWh row; if it is solar/renewable energy, use the current-period solar/generation kWh row. Do not use TOD, slab, charge, amount, rate, date, register, or historical rows. Never switch to a weaker component only to match ERP unit.
37919
+ - Never persist just because a row exists. Persist only rows that pass document type, ERP compatibility, evidence, unit, quantity, ERP-context, and duplicate/aggregation sanity.
37920
+ - It is acceptable to call the same tool multiple times with repaired inputs. It is acceptable to revise groups and rows.
37921
+ - If a group cannot be safely extracted or mapped, call save_review_rows with source pages, evidence, and a clear reason instead of saving an incomplete normal row.
37922
+ - Use persist_validated_rows after validation. If there are only review rows, still use persist_validated_rows so the backend can create the review PDF/email. Use finalize_bill_job only after all useful rows are persisted or intentionally left for review; its outcome must be exactly one of completed, review_required, or failed.
37923
+ - Do not invent emission factors, quantities, units, invoice numbers, or page evidence.
37924
+
37925
+ Your output to the user is the job state and streamed tool activity, so keep tool arguments and notes specific and evidence-backed.`;
37926
+ const promptBulletList = (items) => items.map((item) => `- ${item}`).join('\n');
37927
+ const buildBulkBillAgentSystemPrompt = (context = {}, documentText = '') => {
37928
+ const config = buildBulkBillAgentPromptConfig(context, documentText);
37929
+ const allowedItems = config.allowedItemSummaries.slice(0, 40);
37930
+ return `${baseBulkBillAgentSystemPrompt}
37931
+
37932
+ Active ERP extraction sub-agent contract:
37933
+ Profile: ${config.profile.label} (${config.profile.id})
37934
+ Description: ${config.profile.description}
37935
+ Expected document types: ${config.profile.documentTypes.join(', ') || 'not specified'}
37936
+ Preferred units: ${config.profile.preferredUnits.join(', ') || 'not specified'}
37937
+
37938
+ Upload context:
37939
+ - Scope: ${config.uploadContext.scope || 'not specified'}
37940
+ - Category: ${config.uploadContext.category || 'not specified'}
37941
+ - Plant: ${config.uploadContext.plant || 'not specified'}
37942
+
37943
+ Critical document-period rule:
37944
+ - Do not assume the upload period is the bill period. Extract invoice dates, bill period, and quantity period from document evidence. Use upload context only when the document truly has no period evidence.
37945
+
37946
+ Category-specific extraction rules:
37947
+ ${promptBulletList(config.profile.extractionRules)}
37948
+
37949
+ Category-specific reject rules:
37950
+ ${promptBulletList(config.profile.rejectRules)}
37951
+
37952
+ Allowed ERP items for this upload (${config.allowedItemCount} total, first ${allowedItems.length} shown):
37953
+ ${promptBulletList(allowedItems)}
37954
+
37955
+ Follow this profile unless page evidence clearly proves a different bill type; if evidence conflicts with the ERP page, send rows to review instead of forcing a mapping.`;
37956
+ };
37903
37957
  const numericPattern = /-?(?:(?:\d{1,3}(?:,\d{3})+)|\d+)(?:\.\d+)?/g;
37904
37958
  const physicalUnitPattern = /\b(kwh|kw\s*h|kvah|kva\s*h|mwh|kg|kgs|kilograms?|tonnes?|tons?|mt|kl|litres?|liters?|ltr?s?|m3|m³|scm|ncm|nm3|km|passenger[-\s]?km|room[-\s]?nights?|nights?|cyl(?:inders?)?|nos?|pcs|pieces?)\b/i;
37905
37959
  const metadataOnlyPattern = /(?:₹|rs\.?|inr|amount|payable|charge|tax|gst|duty|cess|rate|tariff|arrear|rebate|subsidy|surcharge|rent|total\s+amount|invoice\s*(?:no|number)|account\s*(?:no|number)|consumer\s*(?:no|number))/i;
@@ -38249,6 +38303,102 @@ const extractBulkBillAgentProfileCandidates = ({ mappingContext = {}, pages = []
38249
38303
  })
38250
38304
  .slice(0, 30);
38251
38305
  };
38306
+ const buildBulkBillAgentRouterPrompt = (context = {}, documentText = '') => {
38307
+ const config = buildBulkBillAgentPromptConfig(context, documentText);
38308
+ return `You are the ZeroCarbon bulk bill router and grouping supervisor.
38309
+
38310
+ Your only job is to prepare worker-ready bill groups.
38311
+
38312
+ Responsibilities:
38313
+ - inspect the ERP page context and allowed items
38314
+ - load document metadata
38315
+ - read OCR text in batches for the whole document
38316
+ - fingerprint pages when useful
38317
+ - compare neighboring page boundaries when useful
38318
+ - stage bill groups
38319
+ - classify each staged group
38320
+ - record ERP compatibility for each staged group
38321
+
38322
+ Do not extract quantities, do not save extracted rows, do not validate rows, and do not persist rows.
38323
+
38324
+ Stop once every page is read and every staged group has both:
38325
+ - a document classification
38326
+ - an ERP compatibility decision
38327
+
38328
+ Locked ERP page context:
38329
+ - profile: ${config.profile.label} (${config.profile.id})
38330
+ - scope: ${config.uploadContext.scope || 'not specified'}
38331
+ - category: ${config.uploadContext.category || 'not specified'}
38332
+ - plant: ${config.uploadContext.plant || 'not specified'}
38333
+
38334
+ Allowed ERP items on this page (${config.allowedItemCount} total):
38335
+ ${promptBulletList(config.allowedItemSummaries.slice(0, 30))}
38336
+
38337
+ If the document appears to contain multiple bills or mixed bill types, stage separate groups. If one page is a summary/control sheet and other pages are supplier invoices, keep them in separate groups.`;
38338
+ };
38339
+ const buildBulkBillAgentWorkerPrompt = ({ mappingContext = {}, groupId, pageNumbers, documentType = 'unknown', documentText = '', }) => {
38340
+ const config = buildBulkBillAgentPromptConfig(mappingContext, documentText);
38341
+ return `You are the ZeroCarbon ${config.profile.label} worker for one staged bill group.
38342
+
38343
+ You must only work on:
38344
+ - groupId: ${groupId}
38345
+ - pages: ${pageNumbers.join(', ')}
38346
+ - classified document type: ${documentType}
38347
+
38348
+ Your job:
38349
+ - inspect only this group's evidence
38350
+ - extract physical activity candidates for this group
38351
+ - repair OCR issues when evidence supports it
38352
+ - search/inspect the locked ERP items for this group
38353
+ - save extracted rows for this group
38354
+ - save review rows for this group when a safe normal row cannot be produced
38355
+
38356
+ Do not regroup the document. Do not validate all rows across the whole job. Do not persist validated rows. Do not finalize the whole job.
38357
+
38358
+ Active extraction profile:
38359
+ - profile: ${config.profile.label} (${config.profile.id})
38360
+ - scope: ${config.uploadContext.scope || 'not specified'}
38361
+ - category: ${config.uploadContext.category || 'not specified'}
38362
+ - plant: ${config.uploadContext.plant || 'not specified'}
38363
+
38364
+ Category-specific extraction rules:
38365
+ ${promptBulletList(config.profile.extractionRules)}
38366
+
38367
+ Category-specific reject rules:
38368
+ ${promptBulletList(config.profile.rejectRules)}
38369
+
38370
+ Allowed ERP items for this worker (${config.allowedItemCount} total):
38371
+ ${promptBulletList(config.allowedItemSummaries.slice(0, 30))}
38372
+
38373
+ Critical rules:
38374
+ - never save rows for any other group
38375
+ - never use another group's page evidence
38376
+ - if the group is incompatible with the ERP page, save review rows instead of forcing mapping
38377
+ - if the document has its own dates or period, use those instead of upload context`;
38378
+ };
38379
+ const buildBulkBillAgentFinalizerPrompt = (context = {}, documentText = '') => {
38380
+ const config = buildBulkBillAgentPromptConfig(context, documentText);
38381
+ return `You are the ZeroCarbon finalizer and persistence worker.
38382
+
38383
+ Your only job is to:
38384
+ - inspect the current workspace state
38385
+ - validate extracted rows against locked ERP items
38386
+ - persist validated rows to the backend
38387
+ - finalize the job with the correct outcome
38388
+
38389
+ Do not read more pages. Do not restage groups. Do not perform new extraction unless there is a critical gap that prevents safe finalization.
38390
+
38391
+ Active ERP page:
38392
+ - profile: ${config.profile.label} (${config.profile.id})
38393
+ - scope: ${config.uploadContext.scope || 'not specified'}
38394
+ - category: ${config.uploadContext.category || 'not specified'}
38395
+
38396
+ Finalize rules:
38397
+ - use outcome completed when backend persistence succeeded, no review rows remain, and backend returned no blocking review/conflict rows
38398
+ - backend skipped duplicates are non-blocking if the mapped row was otherwise persisted or intentionally skipped as a duplicate
38399
+ - use outcome review_required when review rows remain or backend returned blocking review/conflict rows
38400
+ - use outcome failed only for unrecoverable execution errors`;
38401
+ };
38252
38402
 
38253
38403
  // User-specific configurations mapping
38254
38404
  const USER_CONFIGS = {
@@ -45085,7 +45235,11 @@ exports.Industries = index;
45085
45235
  exports.UI_FEATURES = UI_FEATURES;
45086
45236
  exports.WATER_PRODUCTS = WATER_PRODUCTS$2;
45087
45237
  exports.addItemForUser = addItemForUser;
45238
+ exports.buildBulkBillAgentFinalizerPrompt = buildBulkBillAgentFinalizerPrompt;
45088
45239
  exports.buildBulkBillAgentPromptConfig = buildBulkBillAgentPromptConfig;
45240
+ exports.buildBulkBillAgentRouterPrompt = buildBulkBillAgentRouterPrompt;
45241
+ exports.buildBulkBillAgentSystemPrompt = buildBulkBillAgentSystemPrompt;
45242
+ exports.buildBulkBillAgentWorkerPrompt = buildBulkBillAgentWorkerPrompt;
45089
45243
  exports.buildUserConfigItemKey = buildUserConfigItemKey;
45090
45244
  exports.calculateCCTSEmission = calculateCCTSEmission;
45091
45245
  exports.calculateIntensityMetrics = calculateIntensityMetrics;