@utilix-tech/sdk 0.42.0 → 0.44.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/CHANGELOG.md +8 -0
- package/README.md +23 -6
- package/dist/{ai_agent-C1zudGgT.d.cts → ai_agent-CmrVjvYH.d.cts} +28 -2
- package/dist/{ai_agent-C1zudGgT.d.ts → ai_agent-CmrVjvYH.d.ts} +28 -2
- package/dist/{chunk-W3J7GZVQ.js → chunk-EKIXOA7B.js} +114 -1
- package/dist/{chunk-UD45LBG7.js → chunk-GZBSKZ6F.js} +212 -1
- package/dist/{chunk-2MTHD2LG.js → chunk-WT3Q5LCN.js} +56 -1
- package/dist/index.cjs +379 -0
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/{network-oAs83Ztn.d.ts → network-BlOVDE3Y.d.cts} +80 -2
- package/dist/{network-oAs83Ztn.d.cts → network-BlOVDE3Y.d.ts} +80 -2
- package/dist/tools/ai_agent.cjs +113 -0
- package/dist/tools/ai_agent.d.cts +1 -1
- package/dist/tools/ai_agent.d.ts +1 -1
- package/dist/tools/ai_agent.js +1 -1
- package/dist/tools/network.cjs +211 -0
- package/dist/tools/network.d.cts +1 -1
- package/dist/tools/network.d.ts +1 -1
- package/dist/tools/network.js +1 -1
- package/dist/tools/units.cjs +55 -0
- package/dist/tools/units.d.cts +1 -1
- package/dist/tools/units.d.ts +1 -1
- package/dist/tools/units.js +1 -1
- package/dist/{units-CzPwRC03.d.cts → units-WAgBQ7D7.d.cts} +35 -2
- package/dist/{units-CzPwRC03.d.ts → units-WAgBQ7D7.d.ts} +35 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Full release notes for all Utilix surfaces (browser tools, REST API, SDKs, MCP server) live at [utilix.tech/changelog](https://utilix.tech/changelog). This file tracks just this package.
|
|
4
4
|
|
|
5
|
+
## 0.44.0
|
|
6
|
+
- Add `buildPermissionsPolicy`, `parsePermissionsPolicy` (permissions-policy-builder): build a `Permissions-Policy` response header from browser features and their per-feature allowlist with a plain-English note per feature, or parse an existing one into the same shape.
|
|
7
|
+
- Add `calculatePaybackPeriod` (payback-period-calculator): compute the simple and discounted payback period from an initial investment and a series of periodic cash flows.
|
|
8
|
+
|
|
9
|
+
## 0.43.0
|
|
10
|
+
- Add `validateManifest` (manifest-validator): validate a web app manifest.json against the W3C Web App Manifest spec's installability requirements, including a 512x512 icon and a maskable icon check.
|
|
11
|
+
- Add `lintToolSchema` (tool-schema-linter): lint an LLM tool/function-calling definition (OpenAI, Anthropic, or MCP format) for missing descriptions, invalid names, empty enums, and required/properties mismatches.
|
|
12
|
+
|
|
5
13
|
## 0.42.0
|
|
6
14
|
- Add `buildVaryHeader`, `parseVaryHeader` (vary-header-builder): build a `Vary` response header from request-header names with a plain-English caching note per header, or parse an existing Vary header into the same shape.
|
|
7
15
|
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @utilix-tech/sdk
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**626 developer utility functions for Node.js: runs locally, no API key required.**
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@utilix-tech/sdk)
|
|
6
6
|
[](https://www.npmjs.com/package/@utilix-tech/sdk)
|
|
@@ -312,7 +312,7 @@ formatIso8601Duration(90061); // { iso: "P1DT1H1M1S", ... }
|
|
|
312
312
|
### `/units`: Conversions
|
|
313
313
|
|
|
314
314
|
```ts
|
|
315
|
-
import { convertBytes, pxToAll, convert, formatValue, validateCardNumber, validateIban, calculateLoan, validateBarcode, calculateTax, calculateCompoundInterest, validateIsbn, calculateTipSplit, calculateSimpleInterest, calculateTimeValue, calculatePercentageChange, convertAprApy, calculateMarginMarkup, calculateDiscount, applySuccessiveDiscounts, calculateBreakEven, calculateVideoBitrate, calculateRuleOf72, calculateEmi, calculateRoi, compareUnitPrices } from "@utilix-tech/sdk/units";
|
|
315
|
+
import { convertBytes, pxToAll, convert, formatValue, validateCardNumber, validateIban, calculateLoan, validateBarcode, calculateTax, calculateCompoundInterest, validateIsbn, calculateTipSplit, calculateSimpleInterest, calculateTimeValue, calculatePercentageChange, convertAprApy, calculateMarginMarkup, calculateDiscount, applySuccessiveDiscounts, calculateBreakEven, calculateVideoBitrate, calculateRuleOf72, calculateEmi, calculateRoi, compareUnitPrices, calculatePaybackPeriod } from "@utilix-tech/sdk/units";
|
|
316
316
|
|
|
317
317
|
// File sizes
|
|
318
318
|
convertBytes(1073741824, "GB"); // 1
|
|
@@ -422,6 +422,10 @@ calculateCashBreakdown(53.75, USD_DENOMINATIONS);
|
|
|
422
422
|
// Change owed for a payment/tender pair, broken down the same way
|
|
423
423
|
calculateChange(4.65, 5.0, USD_DENOMINATIONS);
|
|
424
424
|
// { changeDue: 0.35, breakdown: [{ denomination: 0.25, count: 1, subtotal: 0.25 }, ...], totalCount: 2 }
|
|
425
|
+
|
|
426
|
+
// Payback period: simple + discounted, from an initial investment and periodic cash flows
|
|
427
|
+
calculatePaybackPeriod({ initialInvestment: 1000, cashFlows: [400, 400, 400], discountRatePercent: 8 });
|
|
428
|
+
// { paybackPeriod: 2.5, paybackPeriodRounded: 3, recovered: true, discountedPaybackPeriod: 2.9029, ... }
|
|
425
429
|
```
|
|
426
430
|
|
|
427
431
|
---
|
|
@@ -433,7 +437,8 @@ import { getStatusCode, isValidIp, isValidIpv4, isValidIpv6,
|
|
|
433
437
|
searchStatusCodes, buildGeoUrl, countryCodeToFlag,
|
|
434
438
|
parseHar, validateSitemap, validateRobotsTxt,
|
|
435
439
|
parseUserAgent, buildCacheControl, buildReferrerPolicy, parseIpv6Address, buildLinkHeader, checkSetCookieHeader, analyzeEmailHeaders,
|
|
436
|
-
buildRangeHeader, parseContentRangeHeader, buildVaryHeader, parseVaryHeader
|
|
440
|
+
buildRangeHeader, parseContentRangeHeader, buildVaryHeader, parseVaryHeader, validateManifest,
|
|
441
|
+
buildPermissionsPolicy, parsePermissionsPolicy } from "@utilix-tech/sdk/network";
|
|
437
442
|
|
|
438
443
|
getStatusCode(404);
|
|
439
444
|
// { code: 404, text: "Not Found", description: "...", category: "Client Error" }
|
|
@@ -504,6 +509,18 @@ buildVaryHeader(["Accept-Encoding", "Accept-Language"]);
|
|
|
504
509
|
// Parse an existing Vary header value into the same shape
|
|
505
510
|
parseVaryHeader("Vary: Accept-Encoding, Accept-Language");
|
|
506
511
|
// { header: "Vary: Accept-Encoding, Accept-Language", entries: [...], warnings: [] }
|
|
512
|
+
|
|
513
|
+
// Validate a web app manifest.json against the W3C spec's installability requirements
|
|
514
|
+
validateManifest(JSON.stringify({ name: "My App", start_url: "/", display: "standalone", icons: [{ src: "/icon-512.png", sizes: "512x512", purpose: "any maskable" }] }));
|
|
515
|
+
// { issues: [...], valid: true, summary: { hasMaskableIcon: true, has512Icon: true, ... } }
|
|
516
|
+
|
|
517
|
+
// Build a Permissions-Policy header from features and their allowlists, with a plain-English note per feature
|
|
518
|
+
buildPermissionsPolicy([{ feature: "camera", allowlist: [] }, { feature: "geolocation", allowlist: ["self"] }]);
|
|
519
|
+
// { header: "Permissions-Policy: camera=(), geolocation=(self)", directives: [...], warnings: [] }
|
|
520
|
+
|
|
521
|
+
// Parse an existing Permissions-Policy header value into the same shape
|
|
522
|
+
parsePermissionsPolicy("camera=(), geolocation=(self)");
|
|
523
|
+
// { header: "Permissions-Policy: camera=(), geolocation=(self)", directives: [...], warnings: [] }
|
|
507
524
|
```
|
|
508
525
|
|
|
509
526
|
---
|
|
@@ -741,14 +758,14 @@ readVideoInfo(new Uint8Array(videoBytes));
|
|
|
741
758
|
| `@utilix-tech/sdk/data` | CSV, YAML, TOML, XML, INI, NDJSON parse and convert, SRT/WebVTT subtitles, Markdown front matter parser |
|
|
742
759
|
| `@utilix-tech/sdk/generators` | UUID v4/v7, ULID, passwords, strength check, entropy estimator, fake data |
|
|
743
760
|
| `@utilix-tech/sdk/time` | Date diff, timezone convert, cron parse, relative time |
|
|
744
|
-
| `@utilix-tech/sdk/units` | Bytes, CSS px/rem, number bases, currency format, credit card/IBAN/barcode/ISBN validation, loan calculator, EMI calculator, compound/simple interest calculators, VAT/sales tax calculator, tip/bill split calculator, break-even point calculator, Rule of 72 calculator, savings goal calculator, ROI calculator, cash denomination/till calculator |
|
|
745
|
-
| `@utilix-tech/sdk/network` | HTTP status codes, IP validation, country flags, geolocation URLs, HAR file parsing, User-Agent parsing, IPv6 address compress/expand |
|
|
761
|
+
| `@utilix-tech/sdk/units` | Bytes, CSS px/rem, number bases, currency format, credit card/IBAN/barcode/ISBN validation, loan calculator, EMI calculator, compound/simple interest calculators, VAT/sales tax calculator, tip/bill split calculator, break-even point calculator, Rule of 72 calculator, savings goal calculator, ROI calculator, cash denomination/till calculator, payback period calculator |
|
|
762
|
+
| `@utilix-tech/sdk/network` | HTTP status codes, IP validation, country flags, geolocation URLs, HAR file parsing, User-Agent parsing, IPv6 address compress/expand, Permissions-Policy header builder |
|
|
746
763
|
| `@utilix-tech/sdk/api` | cURL build/parse, JWT decode/sign, JWKS parse, CORS headers, CSP header |
|
|
747
764
|
| `@utilix-tech/sdk/code` | SQL format/minify, HTML format/minify, regex tester, GraphQL format, MIME type lookup, GitHub URL parsing, regex ReDoS detector, Conventional Commits linter |
|
|
748
765
|
| `@utilix-tech/sdk/color` | Hex/RGB/HSL/HSV/CMYK convert, palette generation, contrast check |
|
|
749
766
|
| `@utilix-tech/sdk/css` | CSS gradient, box-shadow, border-radius, keyframe animation generators |
|
|
750
767
|
| `@utilix-tech/sdk/misc` | SVG optimize/sanitize, file size format, Unicode inspector |
|
|
751
|
-
| `@utilix-tech/sdk/ai_agent` | Token estimate/trim, chunk text, extract URLs/JSON/keywords, sanitize HTML, flatten/merge JSON, dedupe lines, validate schema, PII/secret/injection detect, vector similarity, few-shot prompt formatter |
|
|
768
|
+
| `@utilix-tech/sdk/ai_agent` | Token estimate/trim, chunk text, extract URLs/JSON/keywords, sanitize HTML, flatten/merge JSON, dedupe lines, validate schema, PII/secret/injection detect, vector similarity, few-shot prompt formatter, tool-definition schema linter |
|
|
752
769
|
| `@utilix-tech/sdk/media` | Image format & dimension reading from raw bytes (PNG, JPEG, GIF, WebP, BMP); PDF metadata reading; PDF page dimension/orientation listing; WAV audio info; ID3 tags; ICO favicon inspection; FLAC metadata reading; MP4/WebM video info |
|
|
753
770
|
|
|
754
771
|
---
|
|
@@ -351,6 +351,29 @@ interface FewShotFormatResult {
|
|
|
351
351
|
* the 'delimiter' format and defaults to '---'.
|
|
352
352
|
*/
|
|
353
353
|
declare function formatFewShotExamples(examples: FewShotExample[], format?: FewShotFormat, delimiter?: string): FewShotFormatResult;
|
|
354
|
+
interface ToolSchemaIssue {
|
|
355
|
+
severity: 'error' | 'warning';
|
|
356
|
+
tool: string;
|
|
357
|
+
path: string;
|
|
358
|
+
message: string;
|
|
359
|
+
}
|
|
360
|
+
interface ToolSchemaLintResult {
|
|
361
|
+
toolCount: number;
|
|
362
|
+
issues: ToolSchemaIssue[];
|
|
363
|
+
valid: boolean;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Lint an LLM tool/function-calling definition (OpenAI, Anthropic, or MCP
|
|
367
|
+
* format — a single definition, an array of them, or a `{tools:[...]}`
|
|
368
|
+
* wrapper) for the mistakes that measurably hurt model accuracy: a missing
|
|
369
|
+
* or vague description, a name that doesn't match provider naming rules, a
|
|
370
|
+
* non-object top-level parameter schema, properties missing descriptions,
|
|
371
|
+
* an empty enum, a `required` entry with no matching property, or duplicate
|
|
372
|
+
* tool names in the same list.
|
|
373
|
+
*/
|
|
374
|
+
declare function lintToolSchema(jsonText: string): ToolSchemaLintResult | {
|
|
375
|
+
error: string;
|
|
376
|
+
};
|
|
354
377
|
|
|
355
378
|
type ai_agent_ChunkStrategy = ChunkStrategy;
|
|
356
379
|
type ai_agent_CompressHtmlResult = CompressHtmlResult;
|
|
@@ -393,6 +416,8 @@ type ai_agent_TableResult2 = TableResult2;
|
|
|
393
416
|
type ai_agent_TextChunk = TextChunk;
|
|
394
417
|
type ai_agent_TokenEstimate = TokenEstimate;
|
|
395
418
|
type ai_agent_TokenEstimateResult = TokenEstimateResult;
|
|
419
|
+
type ai_agent_ToolSchemaIssue = ToolSchemaIssue;
|
|
420
|
+
type ai_agent_ToolSchemaLintResult = ToolSchemaLintResult;
|
|
396
421
|
type ai_agent_TrimResult = TrimResult;
|
|
397
422
|
type ai_agent_TrimStrategy = TrimStrategy;
|
|
398
423
|
type ai_agent_UrlMatch = UrlMatch;
|
|
@@ -418,6 +443,7 @@ declare const ai_agent_extractTables: typeof extractTables;
|
|
|
418
443
|
declare const ai_agent_extractUrls: typeof extractUrls;
|
|
419
444
|
declare const ai_agent_flattenJson: typeof flattenJson;
|
|
420
445
|
declare const ai_agent_formatFewShotExamples: typeof formatFewShotExamples;
|
|
446
|
+
declare const ai_agent_lintToolSchema: typeof lintToolSchema;
|
|
421
447
|
declare const ai_agent_mergeJson: typeof mergeJson;
|
|
422
448
|
declare const ai_agent_redactPii: typeof redactPii;
|
|
423
449
|
declare const ai_agent_repairJson: typeof repairJson;
|
|
@@ -430,7 +456,7 @@ declare const ai_agent_unflattenJson: typeof unflattenJson;
|
|
|
430
456
|
declare const ai_agent_validateJsonSchema: typeof validateJsonSchema;
|
|
431
457
|
declare const ai_agent_vectorSimilarity: typeof vectorSimilarity;
|
|
432
458
|
declare namespace ai_agent {
|
|
433
|
-
export { type ai_agent_ChunkStrategy as ChunkStrategy, type ai_agent_CompressHtmlResult as CompressHtmlResult, type ai_agent_CompressJsonResult as CompressJsonResult, type ai_agent_CompressMarkdownResult as CompressMarkdownResult, type ai_agent_CostEstimate as CostEstimate, type ai_agent_DedupeResult as DedupeResult, type ai_agent_DedupeStrategy as DedupeStrategy, type ai_agent_DiffEntry2 as DiffEntry2, type ai_agent_DiffOp2 as DiffOp2, type ai_agent_DiffResult2 as DiffResult2, type ai_agent_Entity2 as Entity2, type ai_agent_EntityType2 as EntityType2, type ai_agent_ExtractJsonResult as ExtractJsonResult, type ai_agent_ExtractKeywordsResult as ExtractKeywordsResult, type ai_agent_ExtractUrlsResult as ExtractUrlsResult, type ai_agent_FewShotExample as FewShotExample, type ai_agent_FewShotFormat as FewShotFormat, type ai_agent_FewShotFormatResult as FewShotFormatResult, type ai_agent_InjectionDetectResult as InjectionDetectResult, type ai_agent_InjectionFinding as InjectionFinding, type ai_agent_JsonBlock as JsonBlock, type ai_agent_JsonRepairResult as JsonRepairResult, type ai_agent_Keyword as Keyword, ai_agent_MODEL_PRICING as MODEL_PRICING, type ai_agent_MergeResult as MergeResult, type ai_agent_MergeStrategy as MergeStrategy, type ai_agent_ModelPricing as ModelPricing, type ai_agent_PiiDetectResult as PiiDetectResult, type ai_agent_PiiFinding as PiiFinding, type ai_agent_PiiType as PiiType, type ai_agent_RankedChunk as RankedChunk, type ai_agent_RelevanceResult as RelevanceResult, type ai_agent_SanitizeResult as SanitizeResult, type ai_agent_SecretDetectResult as SecretDetectResult, type ai_agent_SecretFinding as SecretFinding, type ai_agent_SecretType as SecretType, type ai_agent_SummaryResult as SummaryResult, type ai_agent_TableResult2 as TableResult2, type ai_agent_TextChunk as TextChunk, type ai_agent_TokenEstimate as TokenEstimate, type ai_agent_TokenEstimateResult as TokenEstimateResult, type ai_agent_TrimResult as TrimResult, type ai_agent_TrimStrategy as TrimStrategy, type ai_agent_UrlMatch as UrlMatch, type ai_agent_ValidationError as ValidationError, type ai_agent_ValidationResult as ValidationResult, type ai_agent_VectorSimilarityResult as VectorSimilarityResult, ai_agent_chunkText as chunkText, ai_agent_compressHtml as compressHtml, ai_agent_compressJson as compressJson, ai_agent_compressMarkdown as compressMarkdown, ai_agent_deduplicateLines as deduplicateLines, ai_agent_detectPii as detectPii, ai_agent_detectPromptInjection as detectPromptInjection, ai_agent_detectSecrets as detectSecrets, ai_agent_diffJson as diffJson, ai_agent_estimateCost as estimateCost, ai_agent_estimateTokens as estimateTokens, ai_agent_expandQuery as expandQuery, ai_agent_extractEntities as extractEntities, ai_agent_extractJson as extractJson, ai_agent_extractKeywords as extractKeywords, ai_agent_extractTables as extractTables, ai_agent_extractUrls as extractUrls, ai_agent_flattenJson as flattenJson, ai_agent_formatFewShotExamples as formatFewShotExamples, ai_agent_mergeJson as mergeJson, ai_agent_redactPii as redactPii, ai_agent_repairJson as repairJson, ai_agent_rerankChunks as rerankChunks, ai_agent_sanitizeHtml as sanitizeHtml, ai_agent_scoreRelevance as scoreRelevance, ai_agent_summarizeForLlm as summarizeForLlm, ai_agent_trimToTokens as trimToTokens, ai_agent_unflattenJson as unflattenJson, ai_agent_validateJsonSchema as validateJsonSchema, ai_agent_vectorSimilarity as vectorSimilarity };
|
|
459
|
+
export { type ai_agent_ChunkStrategy as ChunkStrategy, type ai_agent_CompressHtmlResult as CompressHtmlResult, type ai_agent_CompressJsonResult as CompressJsonResult, type ai_agent_CompressMarkdownResult as CompressMarkdownResult, type ai_agent_CostEstimate as CostEstimate, type ai_agent_DedupeResult as DedupeResult, type ai_agent_DedupeStrategy as DedupeStrategy, type ai_agent_DiffEntry2 as DiffEntry2, type ai_agent_DiffOp2 as DiffOp2, type ai_agent_DiffResult2 as DiffResult2, type ai_agent_Entity2 as Entity2, type ai_agent_EntityType2 as EntityType2, type ai_agent_ExtractJsonResult as ExtractJsonResult, type ai_agent_ExtractKeywordsResult as ExtractKeywordsResult, type ai_agent_ExtractUrlsResult as ExtractUrlsResult, type ai_agent_FewShotExample as FewShotExample, type ai_agent_FewShotFormat as FewShotFormat, type ai_agent_FewShotFormatResult as FewShotFormatResult, type ai_agent_InjectionDetectResult as InjectionDetectResult, type ai_agent_InjectionFinding as InjectionFinding, type ai_agent_JsonBlock as JsonBlock, type ai_agent_JsonRepairResult as JsonRepairResult, type ai_agent_Keyword as Keyword, ai_agent_MODEL_PRICING as MODEL_PRICING, type ai_agent_MergeResult as MergeResult, type ai_agent_MergeStrategy as MergeStrategy, type ai_agent_ModelPricing as ModelPricing, type ai_agent_PiiDetectResult as PiiDetectResult, type ai_agent_PiiFinding as PiiFinding, type ai_agent_PiiType as PiiType, type ai_agent_RankedChunk as RankedChunk, type ai_agent_RelevanceResult as RelevanceResult, type ai_agent_SanitizeResult as SanitizeResult, type ai_agent_SecretDetectResult as SecretDetectResult, type ai_agent_SecretFinding as SecretFinding, type ai_agent_SecretType as SecretType, type ai_agent_SummaryResult as SummaryResult, type ai_agent_TableResult2 as TableResult2, type ai_agent_TextChunk as TextChunk, type ai_agent_TokenEstimate as TokenEstimate, type ai_agent_TokenEstimateResult as TokenEstimateResult, type ai_agent_ToolSchemaIssue as ToolSchemaIssue, type ai_agent_ToolSchemaLintResult as ToolSchemaLintResult, type ai_agent_TrimResult as TrimResult, type ai_agent_TrimStrategy as TrimStrategy, type ai_agent_UrlMatch as UrlMatch, type ai_agent_ValidationError as ValidationError, type ai_agent_ValidationResult as ValidationResult, type ai_agent_VectorSimilarityResult as VectorSimilarityResult, ai_agent_chunkText as chunkText, ai_agent_compressHtml as compressHtml, ai_agent_compressJson as compressJson, ai_agent_compressMarkdown as compressMarkdown, ai_agent_deduplicateLines as deduplicateLines, ai_agent_detectPii as detectPii, ai_agent_detectPromptInjection as detectPromptInjection, ai_agent_detectSecrets as detectSecrets, ai_agent_diffJson as diffJson, ai_agent_estimateCost as estimateCost, ai_agent_estimateTokens as estimateTokens, ai_agent_expandQuery as expandQuery, ai_agent_extractEntities as extractEntities, ai_agent_extractJson as extractJson, ai_agent_extractKeywords as extractKeywords, ai_agent_extractTables as extractTables, ai_agent_extractUrls as extractUrls, ai_agent_flattenJson as flattenJson, ai_agent_formatFewShotExamples as formatFewShotExamples, ai_agent_lintToolSchema as lintToolSchema, ai_agent_mergeJson as mergeJson, ai_agent_redactPii as redactPii, ai_agent_repairJson as repairJson, ai_agent_rerankChunks as rerankChunks, ai_agent_sanitizeHtml as sanitizeHtml, ai_agent_scoreRelevance as scoreRelevance, ai_agent_summarizeForLlm as summarizeForLlm, ai_agent_trimToTokens as trimToTokens, ai_agent_unflattenJson as unflattenJson, ai_agent_validateJsonSchema as validateJsonSchema, ai_agent_vectorSimilarity as vectorSimilarity };
|
|
434
460
|
}
|
|
435
461
|
|
|
436
|
-
export {
|
|
462
|
+
export { compressMarkdown as $, type SummaryResult as A, type TextChunk as B, type ChunkStrategy as C, type DedupeResult as D, type Entity2 as E, type FewShotExample as F, type TokenEstimate as G, type TokenEstimateResult as H, type InjectionDetectResult as I, type JsonBlock as J, type Keyword as K, type ToolSchemaIssue as L, MODEL_PRICING as M, type ToolSchemaLintResult as N, type TrimResult as O, type PiiDetectResult as P, type TrimStrategy as Q, type RankedChunk as R, type SanitizeResult as S, type TableResult2 as T, type UrlMatch as U, type ValidationError as V, type ValidationResult as W, type VectorSimilarityResult as X, chunkText as Y, compressHtml as Z, compressJson as _, ai_agent as a, deduplicateLines as a0, detectPii as a1, detectPromptInjection as a2, detectSecrets as a3, diffJson as a4, estimateCost as a5, estimateTokens as a6, expandQuery as a7, extractEntities as a8, extractJson as a9, extractKeywords as aa, extractTables as ab, extractUrls as ac, flattenJson as ad, formatFewShotExamples as ae, lintToolSchema as af, mergeJson as ag, redactPii as ah, repairJson as ai, rerankChunks as aj, sanitizeHtml as ak, scoreRelevance as al, summarizeForLlm as am, trimToTokens as an, unflattenJson as ao, validateJsonSchema as ap, vectorSimilarity as aq, type CompressHtmlResult as b, type CompressJsonResult as c, type CompressMarkdownResult as d, type CostEstimate as e, type DedupeStrategy as f, type DiffEntry2 as g, type DiffOp2 as h, type DiffResult2 as i, type EntityType2 as j, type ExtractJsonResult as k, type ExtractKeywordsResult as l, type ExtractUrlsResult as m, type FewShotFormat as n, type FewShotFormatResult as o, type InjectionFinding as p, type JsonRepairResult as q, type MergeResult as r, type MergeStrategy as s, type ModelPricing as t, type PiiFinding as u, type PiiType as v, type RelevanceResult as w, type SecretDetectResult as x, type SecretFinding as y, type SecretType as z };
|
|
@@ -351,6 +351,29 @@ interface FewShotFormatResult {
|
|
|
351
351
|
* the 'delimiter' format and defaults to '---'.
|
|
352
352
|
*/
|
|
353
353
|
declare function formatFewShotExamples(examples: FewShotExample[], format?: FewShotFormat, delimiter?: string): FewShotFormatResult;
|
|
354
|
+
interface ToolSchemaIssue {
|
|
355
|
+
severity: 'error' | 'warning';
|
|
356
|
+
tool: string;
|
|
357
|
+
path: string;
|
|
358
|
+
message: string;
|
|
359
|
+
}
|
|
360
|
+
interface ToolSchemaLintResult {
|
|
361
|
+
toolCount: number;
|
|
362
|
+
issues: ToolSchemaIssue[];
|
|
363
|
+
valid: boolean;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Lint an LLM tool/function-calling definition (OpenAI, Anthropic, or MCP
|
|
367
|
+
* format — a single definition, an array of them, or a `{tools:[...]}`
|
|
368
|
+
* wrapper) for the mistakes that measurably hurt model accuracy: a missing
|
|
369
|
+
* or vague description, a name that doesn't match provider naming rules, a
|
|
370
|
+
* non-object top-level parameter schema, properties missing descriptions,
|
|
371
|
+
* an empty enum, a `required` entry with no matching property, or duplicate
|
|
372
|
+
* tool names in the same list.
|
|
373
|
+
*/
|
|
374
|
+
declare function lintToolSchema(jsonText: string): ToolSchemaLintResult | {
|
|
375
|
+
error: string;
|
|
376
|
+
};
|
|
354
377
|
|
|
355
378
|
type ai_agent_ChunkStrategy = ChunkStrategy;
|
|
356
379
|
type ai_agent_CompressHtmlResult = CompressHtmlResult;
|
|
@@ -393,6 +416,8 @@ type ai_agent_TableResult2 = TableResult2;
|
|
|
393
416
|
type ai_agent_TextChunk = TextChunk;
|
|
394
417
|
type ai_agent_TokenEstimate = TokenEstimate;
|
|
395
418
|
type ai_agent_TokenEstimateResult = TokenEstimateResult;
|
|
419
|
+
type ai_agent_ToolSchemaIssue = ToolSchemaIssue;
|
|
420
|
+
type ai_agent_ToolSchemaLintResult = ToolSchemaLintResult;
|
|
396
421
|
type ai_agent_TrimResult = TrimResult;
|
|
397
422
|
type ai_agent_TrimStrategy = TrimStrategy;
|
|
398
423
|
type ai_agent_UrlMatch = UrlMatch;
|
|
@@ -418,6 +443,7 @@ declare const ai_agent_extractTables: typeof extractTables;
|
|
|
418
443
|
declare const ai_agent_extractUrls: typeof extractUrls;
|
|
419
444
|
declare const ai_agent_flattenJson: typeof flattenJson;
|
|
420
445
|
declare const ai_agent_formatFewShotExamples: typeof formatFewShotExamples;
|
|
446
|
+
declare const ai_agent_lintToolSchema: typeof lintToolSchema;
|
|
421
447
|
declare const ai_agent_mergeJson: typeof mergeJson;
|
|
422
448
|
declare const ai_agent_redactPii: typeof redactPii;
|
|
423
449
|
declare const ai_agent_repairJson: typeof repairJson;
|
|
@@ -430,7 +456,7 @@ declare const ai_agent_unflattenJson: typeof unflattenJson;
|
|
|
430
456
|
declare const ai_agent_validateJsonSchema: typeof validateJsonSchema;
|
|
431
457
|
declare const ai_agent_vectorSimilarity: typeof vectorSimilarity;
|
|
432
458
|
declare namespace ai_agent {
|
|
433
|
-
export { type ai_agent_ChunkStrategy as ChunkStrategy, type ai_agent_CompressHtmlResult as CompressHtmlResult, type ai_agent_CompressJsonResult as CompressJsonResult, type ai_agent_CompressMarkdownResult as CompressMarkdownResult, type ai_agent_CostEstimate as CostEstimate, type ai_agent_DedupeResult as DedupeResult, type ai_agent_DedupeStrategy as DedupeStrategy, type ai_agent_DiffEntry2 as DiffEntry2, type ai_agent_DiffOp2 as DiffOp2, type ai_agent_DiffResult2 as DiffResult2, type ai_agent_Entity2 as Entity2, type ai_agent_EntityType2 as EntityType2, type ai_agent_ExtractJsonResult as ExtractJsonResult, type ai_agent_ExtractKeywordsResult as ExtractKeywordsResult, type ai_agent_ExtractUrlsResult as ExtractUrlsResult, type ai_agent_FewShotExample as FewShotExample, type ai_agent_FewShotFormat as FewShotFormat, type ai_agent_FewShotFormatResult as FewShotFormatResult, type ai_agent_InjectionDetectResult as InjectionDetectResult, type ai_agent_InjectionFinding as InjectionFinding, type ai_agent_JsonBlock as JsonBlock, type ai_agent_JsonRepairResult as JsonRepairResult, type ai_agent_Keyword as Keyword, ai_agent_MODEL_PRICING as MODEL_PRICING, type ai_agent_MergeResult as MergeResult, type ai_agent_MergeStrategy as MergeStrategy, type ai_agent_ModelPricing as ModelPricing, type ai_agent_PiiDetectResult as PiiDetectResult, type ai_agent_PiiFinding as PiiFinding, type ai_agent_PiiType as PiiType, type ai_agent_RankedChunk as RankedChunk, type ai_agent_RelevanceResult as RelevanceResult, type ai_agent_SanitizeResult as SanitizeResult, type ai_agent_SecretDetectResult as SecretDetectResult, type ai_agent_SecretFinding as SecretFinding, type ai_agent_SecretType as SecretType, type ai_agent_SummaryResult as SummaryResult, type ai_agent_TableResult2 as TableResult2, type ai_agent_TextChunk as TextChunk, type ai_agent_TokenEstimate as TokenEstimate, type ai_agent_TokenEstimateResult as TokenEstimateResult, type ai_agent_TrimResult as TrimResult, type ai_agent_TrimStrategy as TrimStrategy, type ai_agent_UrlMatch as UrlMatch, type ai_agent_ValidationError as ValidationError, type ai_agent_ValidationResult as ValidationResult, type ai_agent_VectorSimilarityResult as VectorSimilarityResult, ai_agent_chunkText as chunkText, ai_agent_compressHtml as compressHtml, ai_agent_compressJson as compressJson, ai_agent_compressMarkdown as compressMarkdown, ai_agent_deduplicateLines as deduplicateLines, ai_agent_detectPii as detectPii, ai_agent_detectPromptInjection as detectPromptInjection, ai_agent_detectSecrets as detectSecrets, ai_agent_diffJson as diffJson, ai_agent_estimateCost as estimateCost, ai_agent_estimateTokens as estimateTokens, ai_agent_expandQuery as expandQuery, ai_agent_extractEntities as extractEntities, ai_agent_extractJson as extractJson, ai_agent_extractKeywords as extractKeywords, ai_agent_extractTables as extractTables, ai_agent_extractUrls as extractUrls, ai_agent_flattenJson as flattenJson, ai_agent_formatFewShotExamples as formatFewShotExamples, ai_agent_mergeJson as mergeJson, ai_agent_redactPii as redactPii, ai_agent_repairJson as repairJson, ai_agent_rerankChunks as rerankChunks, ai_agent_sanitizeHtml as sanitizeHtml, ai_agent_scoreRelevance as scoreRelevance, ai_agent_summarizeForLlm as summarizeForLlm, ai_agent_trimToTokens as trimToTokens, ai_agent_unflattenJson as unflattenJson, ai_agent_validateJsonSchema as validateJsonSchema, ai_agent_vectorSimilarity as vectorSimilarity };
|
|
459
|
+
export { type ai_agent_ChunkStrategy as ChunkStrategy, type ai_agent_CompressHtmlResult as CompressHtmlResult, type ai_agent_CompressJsonResult as CompressJsonResult, type ai_agent_CompressMarkdownResult as CompressMarkdownResult, type ai_agent_CostEstimate as CostEstimate, type ai_agent_DedupeResult as DedupeResult, type ai_agent_DedupeStrategy as DedupeStrategy, type ai_agent_DiffEntry2 as DiffEntry2, type ai_agent_DiffOp2 as DiffOp2, type ai_agent_DiffResult2 as DiffResult2, type ai_agent_Entity2 as Entity2, type ai_agent_EntityType2 as EntityType2, type ai_agent_ExtractJsonResult as ExtractJsonResult, type ai_agent_ExtractKeywordsResult as ExtractKeywordsResult, type ai_agent_ExtractUrlsResult as ExtractUrlsResult, type ai_agent_FewShotExample as FewShotExample, type ai_agent_FewShotFormat as FewShotFormat, type ai_agent_FewShotFormatResult as FewShotFormatResult, type ai_agent_InjectionDetectResult as InjectionDetectResult, type ai_agent_InjectionFinding as InjectionFinding, type ai_agent_JsonBlock as JsonBlock, type ai_agent_JsonRepairResult as JsonRepairResult, type ai_agent_Keyword as Keyword, ai_agent_MODEL_PRICING as MODEL_PRICING, type ai_agent_MergeResult as MergeResult, type ai_agent_MergeStrategy as MergeStrategy, type ai_agent_ModelPricing as ModelPricing, type ai_agent_PiiDetectResult as PiiDetectResult, type ai_agent_PiiFinding as PiiFinding, type ai_agent_PiiType as PiiType, type ai_agent_RankedChunk as RankedChunk, type ai_agent_RelevanceResult as RelevanceResult, type ai_agent_SanitizeResult as SanitizeResult, type ai_agent_SecretDetectResult as SecretDetectResult, type ai_agent_SecretFinding as SecretFinding, type ai_agent_SecretType as SecretType, type ai_agent_SummaryResult as SummaryResult, type ai_agent_TableResult2 as TableResult2, type ai_agent_TextChunk as TextChunk, type ai_agent_TokenEstimate as TokenEstimate, type ai_agent_TokenEstimateResult as TokenEstimateResult, type ai_agent_ToolSchemaIssue as ToolSchemaIssue, type ai_agent_ToolSchemaLintResult as ToolSchemaLintResult, type ai_agent_TrimResult as TrimResult, type ai_agent_TrimStrategy as TrimStrategy, type ai_agent_UrlMatch as UrlMatch, type ai_agent_ValidationError as ValidationError, type ai_agent_ValidationResult as ValidationResult, type ai_agent_VectorSimilarityResult as VectorSimilarityResult, ai_agent_chunkText as chunkText, ai_agent_compressHtml as compressHtml, ai_agent_compressJson as compressJson, ai_agent_compressMarkdown as compressMarkdown, ai_agent_deduplicateLines as deduplicateLines, ai_agent_detectPii as detectPii, ai_agent_detectPromptInjection as detectPromptInjection, ai_agent_detectSecrets as detectSecrets, ai_agent_diffJson as diffJson, ai_agent_estimateCost as estimateCost, ai_agent_estimateTokens as estimateTokens, ai_agent_expandQuery as expandQuery, ai_agent_extractEntities as extractEntities, ai_agent_extractJson as extractJson, ai_agent_extractKeywords as extractKeywords, ai_agent_extractTables as extractTables, ai_agent_extractUrls as extractUrls, ai_agent_flattenJson as flattenJson, ai_agent_formatFewShotExamples as formatFewShotExamples, ai_agent_lintToolSchema as lintToolSchema, ai_agent_mergeJson as mergeJson, ai_agent_redactPii as redactPii, ai_agent_repairJson as repairJson, ai_agent_rerankChunks as rerankChunks, ai_agent_sanitizeHtml as sanitizeHtml, ai_agent_scoreRelevance as scoreRelevance, ai_agent_summarizeForLlm as summarizeForLlm, ai_agent_trimToTokens as trimToTokens, ai_agent_unflattenJson as unflattenJson, ai_agent_validateJsonSchema as validateJsonSchema, ai_agent_vectorSimilarity as vectorSimilarity };
|
|
434
460
|
}
|
|
435
461
|
|
|
436
|
-
export {
|
|
462
|
+
export { compressMarkdown as $, type SummaryResult as A, type TextChunk as B, type ChunkStrategy as C, type DedupeResult as D, type Entity2 as E, type FewShotExample as F, type TokenEstimate as G, type TokenEstimateResult as H, type InjectionDetectResult as I, type JsonBlock as J, type Keyword as K, type ToolSchemaIssue as L, MODEL_PRICING as M, type ToolSchemaLintResult as N, type TrimResult as O, type PiiDetectResult as P, type TrimStrategy as Q, type RankedChunk as R, type SanitizeResult as S, type TableResult2 as T, type UrlMatch as U, type ValidationError as V, type ValidationResult as W, type VectorSimilarityResult as X, chunkText as Y, compressHtml as Z, compressJson as _, ai_agent as a, deduplicateLines as a0, detectPii as a1, detectPromptInjection as a2, detectSecrets as a3, diffJson as a4, estimateCost as a5, estimateTokens as a6, expandQuery as a7, extractEntities as a8, extractJson as a9, extractKeywords as aa, extractTables as ab, extractUrls as ac, flattenJson as ad, formatFewShotExamples as ae, lintToolSchema as af, mergeJson as ag, redactPii as ah, repairJson as ai, rerankChunks as aj, sanitizeHtml as ak, scoreRelevance as al, summarizeForLlm as am, trimToTokens as an, unflattenJson as ao, validateJsonSchema as ap, vectorSimilarity as aq, type CompressHtmlResult as b, type CompressJsonResult as c, type CompressMarkdownResult as d, type CostEstimate as e, type DedupeStrategy as f, type DiffEntry2 as g, type DiffOp2 as h, type DiffResult2 as i, type EntityType2 as j, type ExtractJsonResult as k, type ExtractKeywordsResult as l, type ExtractUrlsResult as m, type FewShotFormat as n, type FewShotFormatResult as o, type InjectionFinding as p, type JsonRepairResult as q, type MergeResult as r, type MergeStrategy as s, type ModelPricing as t, type PiiFinding as u, type PiiType as v, type RelevanceResult as w, type SecretDetectResult as x, type SecretFinding as y, type SecretType as z };
|
|
@@ -23,6 +23,7 @@ __export(ai_agent_exports, {
|
|
|
23
23
|
extractUrls: () => extractUrls,
|
|
24
24
|
flattenJson: () => flattenJson,
|
|
25
25
|
formatFewShotExamples: () => formatFewShotExamples,
|
|
26
|
+
lintToolSchema: () => lintToolSchema,
|
|
26
27
|
mergeJson: () => mergeJson,
|
|
27
28
|
redactPii: () => redactPii,
|
|
28
29
|
repairJson: () => repairJson,
|
|
@@ -1003,5 +1004,117 @@ Output: ${e.output.trim()}`).join("\n\n");
|
|
|
1003
1004
|
}
|
|
1004
1005
|
return { formatted, exampleCount: valid.length, format };
|
|
1005
1006
|
}
|
|
1007
|
+
var TOOL_NAME_RE = /^[a-zA-Z0-9_-]{1,64}$/;
|
|
1008
|
+
function normalizeToolDefs(data) {
|
|
1009
|
+
let rawList;
|
|
1010
|
+
if (Array.isArray(data)) {
|
|
1011
|
+
rawList = data;
|
|
1012
|
+
} else if (data && typeof data === "object" && Array.isArray(data.tools)) {
|
|
1013
|
+
rawList = data.tools;
|
|
1014
|
+
} else {
|
|
1015
|
+
rawList = [data];
|
|
1016
|
+
}
|
|
1017
|
+
const out = [];
|
|
1018
|
+
for (const item of rawList) {
|
|
1019
|
+
if (!item || typeof item !== "object") {
|
|
1020
|
+
return { error: "Each tool definition must be a JSON object" };
|
|
1021
|
+
}
|
|
1022
|
+
const obj = item;
|
|
1023
|
+
if (obj.type === "function" && obj.function && typeof obj.function === "object") {
|
|
1024
|
+
const fn = obj.function;
|
|
1025
|
+
out.push({ name: String(fn.name ?? ""), description: typeof fn.description === "string" ? fn.description : void 0, schema: fn.parameters, format: "openai" });
|
|
1026
|
+
} else if ("input_schema" in obj) {
|
|
1027
|
+
out.push({ name: String(obj.name ?? ""), description: typeof obj.description === "string" ? obj.description : void 0, schema: obj.input_schema, format: "anthropic" });
|
|
1028
|
+
} else if ("inputSchema" in obj) {
|
|
1029
|
+
out.push({ name: String(obj.name ?? ""), description: typeof obj.description === "string" ? obj.description : void 0, schema: obj.inputSchema, format: "mcp" });
|
|
1030
|
+
} else if ("parameters" in obj || "name" in obj) {
|
|
1031
|
+
out.push({ name: String(obj.name ?? ""), description: typeof obj.description === "string" ? obj.description : void 0, schema: obj.parameters, format: "bare" });
|
|
1032
|
+
} else {
|
|
1033
|
+
return { error: 'Unrecognized tool-definition format: expected an OpenAI ({type:"function",function:{...}}), Anthropic ({name,input_schema}), or MCP ({name,inputSchema}) shape' };
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
return out;
|
|
1037
|
+
}
|
|
1038
|
+
function lintToolSchema(jsonText) {
|
|
1039
|
+
if (!jsonText || !jsonText.trim()) return { error: "Input is empty" };
|
|
1040
|
+
let data;
|
|
1041
|
+
try {
|
|
1042
|
+
data = JSON.parse(jsonText);
|
|
1043
|
+
} catch (e) {
|
|
1044
|
+
return { error: `Invalid JSON: ${e.message}` };
|
|
1045
|
+
}
|
|
1046
|
+
const normalized = normalizeToolDefs(data);
|
|
1047
|
+
if ("error" in normalized) return normalized;
|
|
1048
|
+
if (normalized.length === 0) return { error: "No tool definitions found" };
|
|
1049
|
+
const issues = [];
|
|
1050
|
+
const seenNames = /* @__PURE__ */ new Map();
|
|
1051
|
+
for (const tool of normalized) {
|
|
1052
|
+
const label = tool.name || "(unnamed)";
|
|
1053
|
+
seenNames.set(label, (seenNames.get(label) ?? 0) + 1);
|
|
1054
|
+
if (!tool.name) {
|
|
1055
|
+
issues.push({ severity: "error", tool: label, path: "name", message: 'Tool is missing a "name"' });
|
|
1056
|
+
} else if (!TOOL_NAME_RE.test(tool.name)) {
|
|
1057
|
+
issues.push({ severity: "error", tool: label, path: "name", message: `Tool name "${tool.name}" must match ^[a-zA-Z0-9_-]{1,64}$ (letters, digits, underscores, hyphens, max 64 chars) to be accepted by OpenAI/Anthropic function calling` });
|
|
1058
|
+
}
|
|
1059
|
+
if (!tool.description || !tool.description.trim()) {
|
|
1060
|
+
issues.push({ severity: "error", tool: label, path: "description", message: 'Tool is missing a "description" \u2014 the model relies entirely on this text to decide when to call it' });
|
|
1061
|
+
} else {
|
|
1062
|
+
if (tool.description.trim().length < 10) {
|
|
1063
|
+
issues.push({ severity: "warning", tool: label, path: "description", message: "Description is very short; a vague description measurably hurts the model's ability to pick the right tool" });
|
|
1064
|
+
}
|
|
1065
|
+
if (tool.description.length > 1024) {
|
|
1066
|
+
issues.push({ severity: "warning", tool: label, path: "description", message: `Description is ${tool.description.length} characters; long descriptions cost tokens on every request that includes this tool` });
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
if (tool.schema === void 0 || tool.schema === null) {
|
|
1070
|
+
issues.push({ severity: "warning", tool: label, path: "parameters", message: "Tool has no parameter schema; only correct if the tool genuinely takes no arguments" });
|
|
1071
|
+
continue;
|
|
1072
|
+
}
|
|
1073
|
+
if (typeof tool.schema !== "object" || Array.isArray(tool.schema)) {
|
|
1074
|
+
issues.push({ severity: "error", tool: label, path: "parameters", message: "Parameter schema must be a JSON Schema object" });
|
|
1075
|
+
continue;
|
|
1076
|
+
}
|
|
1077
|
+
const schema = tool.schema;
|
|
1078
|
+
if (schema.type !== void 0 && schema.type !== "object") {
|
|
1079
|
+
issues.push({ severity: "error", tool: label, path: "parameters.type", message: `Top-level parameter schema type is "${String(schema.type)}"; OpenAI and Anthropic both require "object" at the top level` });
|
|
1080
|
+
}
|
|
1081
|
+
const properties = schema.properties;
|
|
1082
|
+
if (properties !== void 0 && (typeof properties !== "object" || properties === null || Array.isArray(properties))) {
|
|
1083
|
+
issues.push({ severity: "error", tool: label, path: "parameters.properties", message: '"properties" must be an object' });
|
|
1084
|
+
} else if (properties && typeof properties === "object") {
|
|
1085
|
+
const propsObj = properties;
|
|
1086
|
+
const propNames = Object.keys(propsObj);
|
|
1087
|
+
for (const propName of propNames) {
|
|
1088
|
+
const prop = propsObj[propName];
|
|
1089
|
+
const propPath = `parameters.properties.${propName}`;
|
|
1090
|
+
if (!prop || typeof prop !== "object") {
|
|
1091
|
+
issues.push({ severity: "error", tool: label, path: propPath, message: "Property schema must be an object" });
|
|
1092
|
+
continue;
|
|
1093
|
+
}
|
|
1094
|
+
const propObj = prop;
|
|
1095
|
+
if (!propObj.description) {
|
|
1096
|
+
issues.push({ severity: "warning", tool: label, path: propPath, message: `Property "${propName}" has no description; missing per-parameter descriptions measurably hurt model accuracy on which value to pass` });
|
|
1097
|
+
}
|
|
1098
|
+
if (Array.isArray(propObj.enum) && propObj.enum.length === 0) {
|
|
1099
|
+
issues.push({ severity: "error", tool: label, path: propPath, message: `Property "${propName}" has an empty "enum" array` });
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
if (Array.isArray(schema.required)) {
|
|
1103
|
+
for (const req of schema.required) {
|
|
1104
|
+
if (typeof req === "string" && !propNames.includes(req)) {
|
|
1105
|
+
issues.push({ severity: "error", tool: label, path: "parameters.required", message: `"required" lists "${req}", which isn't defined in "properties"` });
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
for (const [name, count] of seenNames) {
|
|
1112
|
+
if (count > 1 && name !== "(unnamed)") {
|
|
1113
|
+
issues.push({ severity: "error", tool: name, path: "name", message: `Tool name "${name}" is used ${count} times; tool names must be unique within a single request` });
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
const valid = !issues.some((i) => i.severity === "error");
|
|
1117
|
+
return { toolCount: normalized.length, issues, valid };
|
|
1118
|
+
}
|
|
1006
1119
|
|
|
1007
|
-
export { MODEL_PRICING, ai_agent_exports, chunkText, compressHtml, compressJson, compressMarkdown, deduplicateLines, detectPii, detectPromptInjection, detectSecrets, diffJson, estimateCost, estimateTokens, expandQuery, extractEntities, extractJson, extractKeywords, extractTables, extractUrls, flattenJson, formatFewShotExamples, mergeJson, redactPii, repairJson, rerankChunks, sanitizeHtml, scoreRelevance, summarizeForLlm, trimToTokens, unflattenJson, validateJsonSchema, vectorSimilarity };
|
|
1120
|
+
export { MODEL_PRICING, ai_agent_exports, chunkText, compressHtml, compressJson, compressMarkdown, deduplicateLines, detectPii, detectPromptInjection, detectSecrets, diffJson, estimateCost, estimateTokens, expandQuery, extractEntities, extractJson, extractKeywords, extractTables, extractUrls, flattenJson, formatFewShotExamples, lintToolSchema, mergeJson, redactPii, repairJson, rerankChunks, sanitizeHtml, scoreRelevance, summarizeForLlm, trimToTokens, unflattenJson, validateJsonSchema, vectorSimilarity };
|
|
@@ -6,6 +6,7 @@ __export(network_exports, {
|
|
|
6
6
|
DNS_RECORD_TYPES: () => DNS_RECORD_TYPES,
|
|
7
7
|
HTTP_HEADERS: () => HTTP_HEADERS,
|
|
8
8
|
LINK_REL_VALUES: () => LINK_REL_VALUES,
|
|
9
|
+
PERMISSIONS_POLICY_FEATURES: () => PERMISSIONS_POLICY_FEATURES,
|
|
9
10
|
REFERRER_POLICY_VALUES: () => REFERRER_POLICY_VALUES,
|
|
10
11
|
STATUS_CODES: () => STATUS_CODES,
|
|
11
12
|
analyzeEmailHeaders: () => analyzeEmailHeaders,
|
|
@@ -14,6 +15,7 @@ __export(network_exports, {
|
|
|
14
15
|
buildGeoUrl: () => buildGeoUrl,
|
|
15
16
|
buildLinkHeader: () => buildLinkHeader,
|
|
16
17
|
buildMapUrl: () => buildMapUrl,
|
|
18
|
+
buildPermissionsPolicy: () => buildPermissionsPolicy,
|
|
17
19
|
buildRangeHeader: () => buildRangeHeader,
|
|
18
20
|
buildReferrerPolicy: () => buildReferrerPolicy,
|
|
19
21
|
buildVaryHeader: () => buildVaryHeader,
|
|
@@ -37,6 +39,7 @@ __export(network_exports, {
|
|
|
37
39
|
parseGeoResponse: () => parseGeoResponse,
|
|
38
40
|
parseHar: () => parseHar,
|
|
39
41
|
parseIpv6Address: () => parseIpv6Address,
|
|
42
|
+
parsePermissionsPolicy: () => parsePermissionsPolicy,
|
|
40
43
|
parseUserAgent: () => parseUserAgent,
|
|
41
44
|
parseVaryHeader: () => parseVaryHeader,
|
|
42
45
|
searchHeaders: () => searchHeaders,
|
|
@@ -46,6 +49,7 @@ __export(network_exports, {
|
|
|
46
49
|
validateDomain: () => validateDomain,
|
|
47
50
|
validateHeaderName: () => validateHeaderName,
|
|
48
51
|
validateHeaderValue: () => validateHeaderValue,
|
|
52
|
+
validateManifest: () => validateManifest,
|
|
49
53
|
validateRobotsTxt: () => validateRobotsTxt,
|
|
50
54
|
validateSitemap: () => validateSitemap
|
|
51
55
|
});
|
|
@@ -2364,5 +2368,212 @@ function parseVaryHeader(raw) {
|
|
|
2364
2368
|
const headers = withoutLabel.split(",").map((h) => h.trim()).filter((h) => h.length > 0);
|
|
2365
2369
|
return buildVaryHeader(headers);
|
|
2366
2370
|
}
|
|
2371
|
+
var VALID_MANIFEST_DISPLAY = /* @__PURE__ */ new Set(["fullscreen", "standalone", "minimal-ui", "browser"]);
|
|
2372
|
+
function validateManifest(jsonText) {
|
|
2373
|
+
if (!jsonText || !jsonText.trim()) return { error: "Input is empty" };
|
|
2374
|
+
let manifest;
|
|
2375
|
+
try {
|
|
2376
|
+
manifest = JSON.parse(jsonText);
|
|
2377
|
+
} catch (e) {
|
|
2378
|
+
return { error: `Invalid JSON: ${e.message}` };
|
|
2379
|
+
}
|
|
2380
|
+
if (typeof manifest !== "object" || manifest === null || Array.isArray(manifest)) {
|
|
2381
|
+
return { error: "Manifest must be a JSON object" };
|
|
2382
|
+
}
|
|
2383
|
+
const m = manifest;
|
|
2384
|
+
const issues = [];
|
|
2385
|
+
if (!m.name && !m.short_name) {
|
|
2386
|
+
issues.push({ severity: "error", path: "name", message: 'Manifest must have at least one of "name" or "short_name"' });
|
|
2387
|
+
}
|
|
2388
|
+
if (m.name !== void 0 && typeof m.name !== "string") {
|
|
2389
|
+
issues.push({ severity: "error", path: "name", message: '"name" must be a string' });
|
|
2390
|
+
} else if (typeof m.name === "string" && m.name.length > 45) {
|
|
2391
|
+
issues.push({ severity: "warning", path: "name", message: `"name" is ${m.name.length} characters; keep it under ~45 to avoid truncation in install prompts` });
|
|
2392
|
+
}
|
|
2393
|
+
if (m.short_name !== void 0 && typeof m.short_name !== "string") {
|
|
2394
|
+
issues.push({ severity: "error", path: "short_name", message: '"short_name" must be a string' });
|
|
2395
|
+
} else if (typeof m.short_name === "string" && m.short_name.length > 12) {
|
|
2396
|
+
issues.push({ severity: "warning", path: "short_name", message: `"short_name" is ${m.short_name.length} characters; keep it under ~12 to avoid truncation on home screens` });
|
|
2397
|
+
}
|
|
2398
|
+
if (!m.start_url) {
|
|
2399
|
+
issues.push({ severity: "error", path: "start_url", message: 'Manifest is missing "start_url"' });
|
|
2400
|
+
} else if (typeof m.start_url !== "string") {
|
|
2401
|
+
issues.push({ severity: "error", path: "start_url", message: '"start_url" must be a string' });
|
|
2402
|
+
} else if (m.start_url.startsWith("//")) {
|
|
2403
|
+
issues.push({ severity: "warning", path: "start_url", message: '"start_url" looks protocol-relative; use a relative path (e.g. "/") or a full absolute URL instead' });
|
|
2404
|
+
}
|
|
2405
|
+
if (m.display !== void 0) {
|
|
2406
|
+
if (typeof m.display !== "string" || !VALID_MANIFEST_DISPLAY.has(m.display)) {
|
|
2407
|
+
issues.push({ severity: "error", path: "display", message: `"display" must be one of: ${[...VALID_MANIFEST_DISPLAY].join(", ")}` });
|
|
2408
|
+
}
|
|
2409
|
+
} else {
|
|
2410
|
+
issues.push({ severity: "warning", path: "display", message: 'Missing "display"; it defaults to "browser", which will not open the installed app in its own standalone window' });
|
|
2411
|
+
}
|
|
2412
|
+
const icons = [];
|
|
2413
|
+
let hasMaskableIcon = false;
|
|
2414
|
+
let has512Icon = false;
|
|
2415
|
+
if (!Array.isArray(m.icons) || m.icons.length === 0) {
|
|
2416
|
+
issues.push({ severity: "error", path: "icons", message: 'Manifest must have a non-empty "icons" array' });
|
|
2417
|
+
} else {
|
|
2418
|
+
m.icons.forEach((icon, i) => {
|
|
2419
|
+
const path = `icons[${i}]`;
|
|
2420
|
+
if (!icon || typeof icon !== "object") {
|
|
2421
|
+
issues.push({ severity: "error", path, message: "Icon entry must be an object" });
|
|
2422
|
+
return;
|
|
2423
|
+
}
|
|
2424
|
+
const iconObj = icon;
|
|
2425
|
+
if (!iconObj.src || typeof iconObj.src !== "string") {
|
|
2426
|
+
issues.push({ severity: "error", path, message: 'Icon entry is missing a required "src"' });
|
|
2427
|
+
}
|
|
2428
|
+
if (iconObj.sizes !== void 0) {
|
|
2429
|
+
if (typeof iconObj.sizes !== "string" || iconObj.sizes !== "any" && !/^\d+x\d+(\s+\d+x\d+)*$/i.test(iconObj.sizes)) {
|
|
2430
|
+
issues.push({ severity: "warning", path, message: `"sizes" value "${String(iconObj.sizes)}" doesn't match the expected "WIDTHxHEIGHT" format` });
|
|
2431
|
+
} else if (/(^|\s)512x512(\s|$)/i.test(iconObj.sizes)) {
|
|
2432
|
+
has512Icon = true;
|
|
2433
|
+
}
|
|
2434
|
+
}
|
|
2435
|
+
if (typeof iconObj.purpose === "string" && iconObj.purpose.toLowerCase().includes("maskable")) {
|
|
2436
|
+
hasMaskableIcon = true;
|
|
2437
|
+
}
|
|
2438
|
+
icons.push({
|
|
2439
|
+
src: typeof iconObj.src === "string" ? iconObj.src : "",
|
|
2440
|
+
sizes: typeof iconObj.sizes === "string" ? iconObj.sizes : void 0,
|
|
2441
|
+
type: typeof iconObj.type === "string" ? iconObj.type : void 0,
|
|
2442
|
+
purpose: typeof iconObj.purpose === "string" ? iconObj.purpose : void 0
|
|
2443
|
+
});
|
|
2444
|
+
});
|
|
2445
|
+
if (icons.length > 0) {
|
|
2446
|
+
if (!has512Icon) {
|
|
2447
|
+
issues.push({ severity: "warning", path: "icons", message: "No icon sized 512x512 found; this size is used for splash screens and app store listings" });
|
|
2448
|
+
}
|
|
2449
|
+
if (!hasMaskableIcon) {
|
|
2450
|
+
issues.push({ severity: "warning", path: "icons", message: 'No icon with purpose "maskable" (or "any maskable") found; without one, Android may crop your icon into its adaptive icon mask' });
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2454
|
+
if (m.theme_color !== void 0 && typeof m.theme_color !== "string") {
|
|
2455
|
+
issues.push({ severity: "error", path: "theme_color", message: '"theme_color" must be a CSS color string' });
|
|
2456
|
+
}
|
|
2457
|
+
if (m.background_color !== void 0 && typeof m.background_color !== "string") {
|
|
2458
|
+
issues.push({ severity: "error", path: "background_color", message: '"background_color" must be a CSS color string' });
|
|
2459
|
+
} else if (m.background_color === void 0) {
|
|
2460
|
+
issues.push({ severity: "warning", path: "background_color", message: 'Missing "background_color"; without it the splash screen background defaults to white' });
|
|
2461
|
+
}
|
|
2462
|
+
const valid = !issues.some((i) => i.severity === "error");
|
|
2463
|
+
return {
|
|
2464
|
+
issues,
|
|
2465
|
+
valid,
|
|
2466
|
+
summary: {
|
|
2467
|
+
name: typeof m.name === "string" ? m.name : void 0,
|
|
2468
|
+
shortName: typeof m.short_name === "string" ? m.short_name : void 0,
|
|
2469
|
+
startUrl: typeof m.start_url === "string" ? m.start_url : void 0,
|
|
2470
|
+
display: typeof m.display === "string" ? m.display : void 0,
|
|
2471
|
+
icons,
|
|
2472
|
+
hasMaskableIcon,
|
|
2473
|
+
has512Icon
|
|
2474
|
+
}
|
|
2475
|
+
};
|
|
2476
|
+
}
|
|
2477
|
+
var PERMISSIONS_POLICY_NOTES = {
|
|
2478
|
+
camera: "Controls access to video capture devices (getUserMedia video).",
|
|
2479
|
+
microphone: "Controls access to audio capture devices (getUserMedia audio).",
|
|
2480
|
+
geolocation: "Controls access to the Geolocation API.",
|
|
2481
|
+
autoplay: "Controls whether media elements can autoplay without a user gesture.",
|
|
2482
|
+
fullscreen: "Controls access to the Fullscreen API (requestFullscreen).",
|
|
2483
|
+
payment: "Controls access to the Payment Request API.",
|
|
2484
|
+
usb: "Controls access to the WebUSB API.",
|
|
2485
|
+
accelerometer: "Controls access to the Accelerometer sensor API.",
|
|
2486
|
+
gyroscope: "Controls access to the Gyroscope sensor API.",
|
|
2487
|
+
magnetometer: "Controls access to the Magnetometer sensor API.",
|
|
2488
|
+
midi: "Controls access to the Web MIDI API.",
|
|
2489
|
+
"picture-in-picture": "Controls whether video elements can enter picture-in-picture mode.",
|
|
2490
|
+
"sync-xhr": "Controls whether synchronous XMLHttpRequest is allowed.",
|
|
2491
|
+
"display-capture": "Controls access to screen/tab capture (getDisplayMedia).",
|
|
2492
|
+
"encrypted-media": "Controls access to the Encrypted Media Extensions API (DRM playback).",
|
|
2493
|
+
"clipboard-read": "Controls read access to the async Clipboard API.",
|
|
2494
|
+
"clipboard-write": "Controls write access to the async Clipboard API.",
|
|
2495
|
+
"screen-wake-lock": "Controls access to the Screen Wake Lock API.",
|
|
2496
|
+
"web-share": "Controls access to the Web Share API.",
|
|
2497
|
+
"xr-spatial-tracking": "Controls access to WebXR device sensors and spatial tracking."
|
|
2498
|
+
};
|
|
2499
|
+
var PERMISSIONS_POLICY_FEATURES = Object.keys(PERMISSIONS_POLICY_NOTES);
|
|
2500
|
+
function _formatPermissionsPolicyAllowlist(allowlist) {
|
|
2501
|
+
if (allowlist.includes("*")) return "*";
|
|
2502
|
+
if (allowlist.length === 0) return "()";
|
|
2503
|
+
return "(" + allowlist.map((o) => o === "self" ? "self" : `"${o}"`).join(" ") + ")";
|
|
2504
|
+
}
|
|
2505
|
+
function buildPermissionsPolicy(features) {
|
|
2506
|
+
if (!Array.isArray(features) || features.length === 0) return { error: "At least one feature is required" };
|
|
2507
|
+
const warnings = [];
|
|
2508
|
+
const seen = /* @__PURE__ */ new Map();
|
|
2509
|
+
for (const f of features) {
|
|
2510
|
+
if (!f || typeof f.feature !== "string" || f.feature.trim() === "") continue;
|
|
2511
|
+
const name = f.feature.trim().toLowerCase();
|
|
2512
|
+
const allowlist = Array.isArray(f.allowlist) ? f.allowlist.map((o) => typeof o === "string" ? o.trim() : "").filter((o) => o.length > 0) : [];
|
|
2513
|
+
if (seen.has(name)) warnings.push(`duplicate feature "${name}" was merged, the last occurrence wins`);
|
|
2514
|
+
seen.set(name, { feature: name, allowlist });
|
|
2515
|
+
}
|
|
2516
|
+
if (seen.size === 0) return { error: "At least one feature is required" };
|
|
2517
|
+
const directives = [];
|
|
2518
|
+
for (const { feature, allowlist } of seen.values()) {
|
|
2519
|
+
if (!PERMISSIONS_POLICY_NOTES[feature]) {
|
|
2520
|
+
warnings.push(`"${feature}" is not a widely recognized feature name, it will still be included as written`);
|
|
2521
|
+
}
|
|
2522
|
+
if (allowlist.includes("*") && allowlist.length > 1) {
|
|
2523
|
+
warnings.push(`"${feature}" combines "*" with other origins; "*" already allows every origin so the others are redundant`);
|
|
2524
|
+
}
|
|
2525
|
+
const invalidOrigin = allowlist.find((o) => o !== "self" && o !== "*" && !/^https?:\/\//i.test(o));
|
|
2526
|
+
if (invalidOrigin) {
|
|
2527
|
+
warnings.push(`"${invalidOrigin}" on "${feature}" doesn't look like an origin (expected "self", "*", or an http(s):// URL); it will still be quoted as written`);
|
|
2528
|
+
}
|
|
2529
|
+
directives.push({
|
|
2530
|
+
feature,
|
|
2531
|
+
value: _formatPermissionsPolicyAllowlist(allowlist),
|
|
2532
|
+
note: PERMISSIONS_POLICY_NOTES[feature] ?? `Controls access to the "${feature}" feature.`
|
|
2533
|
+
});
|
|
2534
|
+
}
|
|
2535
|
+
const headerValue = directives.map((d) => `${d.feature}=${d.value}`).join(", ");
|
|
2536
|
+
return { header: `Permissions-Policy: ${headerValue}`, headerValue, directives, warnings };
|
|
2537
|
+
}
|
|
2538
|
+
function _splitPermissionsPolicyTopLevel(input) {
|
|
2539
|
+
const segments = [];
|
|
2540
|
+
let depth = 0;
|
|
2541
|
+
let current = "";
|
|
2542
|
+
for (const ch of input) {
|
|
2543
|
+
if (ch === "(") depth++;
|
|
2544
|
+
if (ch === ")") depth--;
|
|
2545
|
+
if (ch === "," && depth === 0) {
|
|
2546
|
+
if (current.trim()) segments.push(current.trim());
|
|
2547
|
+
current = "";
|
|
2548
|
+
} else {
|
|
2549
|
+
current += ch;
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
if (current.trim()) segments.push(current.trim());
|
|
2553
|
+
return segments;
|
|
2554
|
+
}
|
|
2555
|
+
function _parsePermissionsPolicyAllowlist(rawValue) {
|
|
2556
|
+
if (rawValue === "*") return ["*"];
|
|
2557
|
+
if (rawValue === "()" || rawValue === "") return [];
|
|
2558
|
+
const inner = rawValue.replace(/^\(/, "").replace(/\)$/, "");
|
|
2559
|
+
const tokens = inner.match(/"[^"]*"|\S+/g) ?? [];
|
|
2560
|
+
return tokens.map((t) => t.replace(/^"|"$/g, ""));
|
|
2561
|
+
}
|
|
2562
|
+
function parsePermissionsPolicy(raw) {
|
|
2563
|
+
if (!raw || raw.trim() === "") return { error: "Input is empty" };
|
|
2564
|
+
const withoutLabel = raw.trim().replace(/^permissions-policy:\s*/i, "");
|
|
2565
|
+
const segments = _splitPermissionsPolicyTopLevel(withoutLabel);
|
|
2566
|
+
if (segments.length === 0) return { error: "No directives found" };
|
|
2567
|
+
const features = [];
|
|
2568
|
+
for (const segment of segments) {
|
|
2569
|
+
const eq = segment.indexOf("=");
|
|
2570
|
+
if (eq === -1) continue;
|
|
2571
|
+
const feature = segment.slice(0, eq).trim();
|
|
2572
|
+
const rawValue = segment.slice(eq + 1).trim();
|
|
2573
|
+
features.push({ feature, allowlist: _parsePermissionsPolicyAllowlist(rawValue) });
|
|
2574
|
+
}
|
|
2575
|
+
if (features.length === 0) return { error: "No directives found" };
|
|
2576
|
+
return buildPermissionsPolicy(features);
|
|
2577
|
+
}
|
|
2367
2578
|
|
|
2368
|
-
export { DNS_RECORD_TYPES, HTTP_HEADERS, LINK_REL_VALUES, REFERRER_POLICY_VALUES, STATUS_CODES, analyzeEmailHeaders, buildCacheControl, buildDnsQueryUrl, buildGeoUrl, buildLinkHeader, buildMapUrl, buildRangeHeader, buildReferrerPolicy, buildVaryHeader, checkSetCookieHeader, countryCodeToFlag, formatCoordinates, formatTtl, getByCategory, getHeader, getHeadersByCategory, getStatusByCategory, getStatusCode, isClientError, isServerError, isSuccess, isValidIp, isValidIpv4, isValidIpv6, network_exports, parseContentRangeHeader, parseDnsResponse, parseGeoResponse, parseHar, parseIpv6Address, parseUserAgent, parseVaryHeader, searchHeaders, searchStatusCodes, statusCodeToText, typeNumberToLabel, validateDomain, validateHeaderName, validateHeaderValue, validateRobotsTxt, validateSitemap };
|
|
2579
|
+
export { DNS_RECORD_TYPES, HTTP_HEADERS, LINK_REL_VALUES, PERMISSIONS_POLICY_FEATURES, REFERRER_POLICY_VALUES, STATUS_CODES, analyzeEmailHeaders, buildCacheControl, buildDnsQueryUrl, buildGeoUrl, buildLinkHeader, buildMapUrl, buildPermissionsPolicy, buildRangeHeader, buildReferrerPolicy, buildVaryHeader, checkSetCookieHeader, countryCodeToFlag, formatCoordinates, formatTtl, getByCategory, getHeader, getHeadersByCategory, getStatusByCategory, getStatusCode, isClientError, isServerError, isSuccess, isValidIp, isValidIpv4, isValidIpv6, network_exports, parseContentRangeHeader, parseDnsResponse, parseGeoResponse, parseHar, parseIpv6Address, parsePermissionsPolicy, parseUserAgent, parseVaryHeader, searchHeaders, searchStatusCodes, statusCodeToText, typeNumberToLabel, validateDomain, validateHeaderName, validateHeaderValue, validateManifest, validateRobotsTxt, validateSitemap };
|