@tangle-network/agent-interface 2.9.0 → 2.10.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.
@@ -12,6 +12,7 @@
12
12
  * fixed. This package is the canonical public home for these symbols.
13
13
  */
14
14
  import type { HarnessType } from "./harness.js";
15
+ import type { Sha256Digest } from "./agent-candidate.js";
15
16
  /**
16
17
  * Permission policy value for a capability.
17
18
  */
@@ -343,6 +344,53 @@ export interface AgentProfileConnection {
343
344
  */
344
345
  alias?: string;
345
346
  }
347
+ /** Router namespace reserved for checkpoint-backed models. Receipt-free profiles cannot use it. */
348
+ export declare const TRAINED_MODEL_PREFIX = "tangle-trained/";
349
+ /** An immutable Router alias; serving must independently attest this artifact-to-route binding. */
350
+ export declare function trainedModelIdForArtifact(digest: Sha256Digest): string;
351
+ /** Identity of a task whose data was exposed to training or model selection. */
352
+ export interface AgentTrainingTask {
353
+ benchmark: string;
354
+ task: string;
355
+ contentDigest: Sha256Digest;
356
+ }
357
+ /** Complete exposure inventory, derived from the exact dataset delivered to a trainer. */
358
+ export interface AgentTrainingDatasetIdentity {
359
+ digest: Sha256Digest;
360
+ taskSetDigest: Sha256Digest;
361
+ tasks: AgentTrainingTask[];
362
+ }
363
+ export interface AgentTrainingReceipt {
364
+ version: 1;
365
+ dataset: AgentTrainingDatasetIdentity;
366
+ parentProfileDigest: Sha256Digest;
367
+ /** Null only when the parent has no training receipt. */
368
+ parentReceiptDigest: Sha256Digest | null;
369
+ executionRef: Sha256Digest;
370
+ trainer: {
371
+ mode: "command" | "managed";
372
+ id: string;
373
+ revision: Sha256Digest;
374
+ /** Public hyperparameters only; credentials belong to the private executor. */
375
+ parameters: Record<string, string | number | boolean | null>;
376
+ };
377
+ checkpoint: {
378
+ artifactDigest: Sha256Digest;
379
+ artifactBytes: number;
380
+ routerModelId: string;
381
+ /** Digest of independently verified serving evidence, not trainer stdout. */
382
+ servingDigest: Sha256Digest;
383
+ };
384
+ }
385
+ export interface AgentProfileTraining {
386
+ receipt: AgentTrainingReceipt;
387
+ /** Immediate parent first, terminating at a receipt with parentReceiptDigest=null. */
388
+ ancestors: AgentTrainingReceipt[];
389
+ }
390
+ export interface AgentProfileMetadata extends Record<string, unknown> {
391
+ /** Reserved: a trained model is admitted only with a complete checkpoint receipt. */
392
+ training?: AgentProfileTraining;
393
+ }
346
394
  /**
347
395
  * Public provider-neutral agent profile contract.
348
396
  */
@@ -374,7 +422,7 @@ export interface AgentProfile {
374
422
  hooks?: Record<string, AgentProfileHookCommand[]>;
375
423
  modes?: Record<string, AgentProfileMode>;
376
424
  confidential?: AgentProfileConfidential;
377
- metadata?: Record<string, unknown>;
425
+ metadata?: AgentProfileMetadata;
378
426
  /**
379
427
  * Non-portable backend-specific extensions.
380
428
  *
@@ -63,6 +63,12 @@ export function defineAgentProfileSecretRef(key, format) {
63
63
  ...(format === undefined ? {} : { format }),
64
64
  };
65
65
  }
66
+ /** Router namespace reserved for checkpoint-backed models. Receipt-free profiles cannot use it. */
67
+ export const TRAINED_MODEL_PREFIX = "tangle-trained/";
68
+ /** An immutable Router alias; serving must independently attest this artifact-to-route binding. */
69
+ export function trainedModelIdForArtifact(digest) {
70
+ return `${TRAINED_MODEL_PREFIX}${digest.slice("sha256:".length)}`;
71
+ }
66
72
  /**
67
73
  * Helper for declaring typed profiles in application code.
68
74
  */
@@ -216,7 +216,7 @@ export declare const AgentInteractiveSessionStartSchema: z.ZodObject<{
216
216
  sealed: z.ZodOptional<z.ZodBoolean>;
217
217
  attestationRefresh: z.ZodOptional<z.ZodBoolean>;
218
218
  }, z.core.$strict>>;
219
- metadata: z.ZodOptional<z.ZodType<Record<string, unknown>, unknown, z.core.$ZodTypeInternals<Record<string, unknown>, unknown>>>;
219
+ metadata: z.ZodOptional<z.ZodType<import("./agent-profile.js").AgentProfileMetadata, unknown, z.core.$ZodTypeInternals<import("./agent-profile.js").AgentProfileMetadata, unknown>>>;
220
220
  extensions: z.ZodOptional<z.ZodType<Record<string, Record<string, unknown> | undefined>, unknown, z.core.$ZodTypeInternals<Record<string, Record<string, unknown> | undefined>, unknown>>>;
221
221
  }, z.core.$strict>;
222
222
  requestedProfileDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { type AgentProfile, type AgentProfileMcpServer } from "./agent-profile.js";
2
+ import { type AgentProfile, type AgentProfileMetadata, type AgentTrainingTask, type AgentProfileMcpServer } from "./agent-profile.js";
3
3
  import type { AgentProfileDiff } from "./profile-diff.js";
4
4
  import { type SandboxSizePreset } from "./sandbox-size.js";
5
5
  export declare const agentProfilePermissionValueSchema: z.ZodEnum<{
@@ -326,6 +326,116 @@ export declare const agentProfileDiffRemovalSchema: z.ZodObject<{
326
326
  metadata: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
327
327
  extensions: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
328
328
  }, z.core.$strict>;
329
+ export declare const agentTrainingTaskSchema: z.ZodObject<{
330
+ benchmark: z.ZodString;
331
+ task: z.ZodString;
332
+ contentDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
333
+ }, z.core.$strict>;
334
+ /** The same order is used by dataset ingestion, receipt admission and holdout checks. */
335
+ export declare function agentTrainingTaskKey(task: AgentTrainingTask): string;
336
+ export declare const agentTrainingDatasetIdentitySchema: z.ZodObject<{
337
+ digest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
338
+ taskSetDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
339
+ tasks: z.ZodArray<z.ZodObject<{
340
+ benchmark: z.ZodString;
341
+ task: z.ZodString;
342
+ contentDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
343
+ }, z.core.$strict>>;
344
+ }, z.core.$strict>;
345
+ export declare const agentTrainingParametersSchema: z.ZodType<Record<string, string | number | boolean | null>, unknown, z.core.$ZodTypeInternals<Record<string, string | number | boolean | null>, unknown>>;
346
+ export declare const agentTrainingReceiptSchema: z.ZodObject<{
347
+ version: z.ZodLiteral<1>;
348
+ dataset: z.ZodObject<{
349
+ digest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
350
+ taskSetDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
351
+ tasks: z.ZodArray<z.ZodObject<{
352
+ benchmark: z.ZodString;
353
+ task: z.ZodString;
354
+ contentDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
355
+ }, z.core.$strict>>;
356
+ }, z.core.$strict>;
357
+ parentProfileDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
358
+ parentReceiptDigest: z.ZodNullable<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>;
359
+ executionRef: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
360
+ trainer: z.ZodObject<{
361
+ mode: z.ZodEnum<{
362
+ command: "command";
363
+ managed: "managed";
364
+ }>;
365
+ id: z.ZodString;
366
+ revision: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
367
+ parameters: z.ZodType<Record<string, string | number | boolean | null>, unknown, z.core.$ZodTypeInternals<Record<string, string | number | boolean | null>, unknown>>;
368
+ }, z.core.$strict>;
369
+ checkpoint: z.ZodObject<{
370
+ artifactDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
371
+ artifactBytes: z.ZodNumber;
372
+ routerModelId: z.ZodString;
373
+ servingDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
374
+ }, z.core.$strict>;
375
+ }, z.core.$strict>;
376
+ export declare const agentProfileTrainingSchema: z.ZodObject<{
377
+ receipt: z.ZodObject<{
378
+ version: z.ZodLiteral<1>;
379
+ dataset: z.ZodObject<{
380
+ digest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
381
+ taskSetDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
382
+ tasks: z.ZodArray<z.ZodObject<{
383
+ benchmark: z.ZodString;
384
+ task: z.ZodString;
385
+ contentDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
386
+ }, z.core.$strict>>;
387
+ }, z.core.$strict>;
388
+ parentProfileDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
389
+ parentReceiptDigest: z.ZodNullable<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>;
390
+ executionRef: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
391
+ trainer: z.ZodObject<{
392
+ mode: z.ZodEnum<{
393
+ command: "command";
394
+ managed: "managed";
395
+ }>;
396
+ id: z.ZodString;
397
+ revision: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
398
+ parameters: z.ZodType<Record<string, string | number | boolean | null>, unknown, z.core.$ZodTypeInternals<Record<string, string | number | boolean | null>, unknown>>;
399
+ }, z.core.$strict>;
400
+ checkpoint: z.ZodObject<{
401
+ artifactDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
402
+ artifactBytes: z.ZodNumber;
403
+ routerModelId: z.ZodString;
404
+ servingDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
405
+ }, z.core.$strict>;
406
+ }, z.core.$strict>;
407
+ ancestors: z.ZodArray<z.ZodObject<{
408
+ version: z.ZodLiteral<1>;
409
+ dataset: z.ZodObject<{
410
+ digest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
411
+ taskSetDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
412
+ tasks: z.ZodArray<z.ZodObject<{
413
+ benchmark: z.ZodString;
414
+ task: z.ZodString;
415
+ contentDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
416
+ }, z.core.$strict>>;
417
+ }, z.core.$strict>;
418
+ parentProfileDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
419
+ parentReceiptDigest: z.ZodNullable<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>;
420
+ executionRef: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
421
+ trainer: z.ZodObject<{
422
+ mode: z.ZodEnum<{
423
+ command: "command";
424
+ managed: "managed";
425
+ }>;
426
+ id: z.ZodString;
427
+ revision: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
428
+ parameters: z.ZodType<Record<string, string | number | boolean | null>, unknown, z.core.$ZodTypeInternals<Record<string, string | number | boolean | null>, unknown>>;
429
+ }, z.core.$strict>;
430
+ checkpoint: z.ZodObject<{
431
+ artifactDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
432
+ artifactBytes: z.ZodNumber;
433
+ routerModelId: z.ZodString;
434
+ servingDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
435
+ }, z.core.$strict>;
436
+ }, z.core.$strict>>;
437
+ }, z.core.$strict>;
438
+ export declare const agentProfileMetadataSchema: z.ZodType<AgentProfileMetadata>;
329
439
  /**
330
440
  * The complete provider-neutral agent profile schema — the runtime validator for
331
441
  * the canonical {@link AgentProfile} TS contract. Kept structurally in lock-step
@@ -523,7 +633,7 @@ export declare const agentProfileSchema: z.ZodObject<{
523
633
  sealed: z.ZodOptional<z.ZodBoolean>;
524
634
  attestationRefresh: z.ZodOptional<z.ZodBoolean>;
525
635
  }, z.core.$strict>>;
526
- metadata: z.ZodOptional<z.ZodType<Record<string, unknown>, unknown, z.core.$ZodTypeInternals<Record<string, unknown>, unknown>>>;
636
+ metadata: z.ZodOptional<z.ZodType<AgentProfileMetadata, unknown, z.core.$ZodTypeInternals<AgentProfileMetadata, unknown>>>;
527
637
  extensions: z.ZodOptional<z.ZodType<Record<string, Record<string, unknown> | undefined>, unknown, z.core.$ZodTypeInternals<Record<string, Record<string, unknown> | undefined>, unknown>>>;
528
638
  }, z.core.$strict>;
529
639
  /**
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
- import { REASONING_EFFORTS, } from "./agent-profile.js";
3
- import { environmentNameSchema, headerNameSchema, isSafeExecutable, isSafeRelativePath, isWellFormedUnicode, looksLikeCredential, } from "./agent-candidate-schema-common.js";
2
+ import { REASONING_EFFORTS, TRAINED_MODEL_PREFIX, trainedModelIdForArtifact, } from "./agent-profile.js";
3
+ import { canonicalCandidateDigest, sha256DigestSchema, environmentNameSchema, headerNameSchema, isSafeExecutable, isSafeRelativePath, isWellFormedUnicode, looksLikeCredential, } from "./agent-candidate-schema-common.js";
4
4
  import { harnessTypeSchema } from "./harness.js";
5
5
  import { SANDBOX_SIZE_PRESET_NAMES, } from "./sandbox-size.js";
6
6
  /**
@@ -322,6 +322,88 @@ export const agentProfileDiffRemovalSchema = z.strictObject({
322
322
  metadata: removeListSchema.optional(),
323
323
  extensions: removeListSchema.optional(),
324
324
  });
325
+ const trainingIdentitySchema = z.string().min(1).max(500).refine((value) => value.trim() === value && isWellFormedUnicode(value) &&
326
+ !controlCharacterPattern.test(value) && !looksLikeCredential(value), "training identity must be canonical public text");
327
+ export const agentTrainingTaskSchema = z.strictObject({
328
+ benchmark: trainingIdentitySchema,
329
+ task: trainingIdentitySchema,
330
+ contentDigest: sha256DigestSchema,
331
+ });
332
+ /** The same order is used by dataset ingestion, receipt admission and holdout checks. */
333
+ export function agentTrainingTaskKey(task) {
334
+ return JSON.stringify([task.benchmark, task.task, task.contentDigest]);
335
+ }
336
+ export const agentTrainingDatasetIdentitySchema = z.strictObject({
337
+ digest: sha256DigestSchema,
338
+ taskSetDigest: sha256DigestSchema,
339
+ tasks: z.array(agentTrainingTaskSchema).min(1).max(10_000),
340
+ }).superRefine((dataset, context) => {
341
+ const keys = dataset.tasks.map(agentTrainingTaskKey);
342
+ if (keys.some((key, index) => index > 0 && key <= keys[index - 1])) {
343
+ context.addIssue({ code: "custom", path: ["tasks"], message: "training tasks must be sorted and unique" });
344
+ }
345
+ if (canonicalCandidateDigest(dataset.tasks) !== dataset.taskSetDigest) {
346
+ context.addIssue({ code: "custom", path: ["taskSetDigest"], message: "training task inventory digest mismatch" });
347
+ }
348
+ });
349
+ export const agentTrainingParametersSchema = ownPropertyRecordSchema(z.union([z.string().max(2_048).pipe(publicProfileConfigStringSchema), z.number().finite(), z.boolean(), z.null()])).superRefine((parameters, context) => {
350
+ if (Object.keys(parameters).length > 100) {
351
+ context.addIssue({ code: "custom", message: "at most 100 public training parameters are allowed" });
352
+ }
353
+ for (const name of Object.keys(parameters)) {
354
+ if (!trainingIdentitySchema.safeParse(name).success || isCredentialBearingProfileConfigName(name)) {
355
+ context.addIssue({ code: "custom", path: [name], message: "training parameter name must be public and non-credential" });
356
+ }
357
+ }
358
+ });
359
+ export const agentTrainingReceiptSchema = z.strictObject({
360
+ version: z.literal(1),
361
+ dataset: agentTrainingDatasetIdentitySchema,
362
+ parentProfileDigest: sha256DigestSchema,
363
+ parentReceiptDigest: sha256DigestSchema.nullable(),
364
+ executionRef: sha256DigestSchema,
365
+ trainer: z.strictObject({
366
+ mode: z.enum(["command", "managed"]),
367
+ id: trainingIdentitySchema,
368
+ revision: sha256DigestSchema,
369
+ parameters: agentTrainingParametersSchema,
370
+ }),
371
+ checkpoint: z.strictObject({
372
+ artifactDigest: sha256DigestSchema,
373
+ artifactBytes: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
374
+ routerModelId: trainingIdentitySchema,
375
+ servingDigest: sha256DigestSchema,
376
+ }),
377
+ }).superRefine((receipt, context) => {
378
+ if (receipt.checkpoint.routerModelId !== trainedModelIdForArtifact(receipt.checkpoint.artifactDigest)) {
379
+ context.addIssue({ code: "custom", path: ["checkpoint", "routerModelId"], message: "trained Router model must be artifact-addressed" });
380
+ }
381
+ });
382
+ export const agentProfileTrainingSchema = z.strictObject({
383
+ receipt: agentTrainingReceiptSchema,
384
+ ancestors: z.array(agentTrainingReceiptSchema).max(8),
385
+ }).superRefine((training, context) => {
386
+ const chain = [training.receipt, ...training.ancestors];
387
+ const digests = chain.map(canonicalCandidateDigest);
388
+ if (new Set(digests).size !== digests.length) {
389
+ context.addIssue({ code: "custom", message: "training receipt ancestry must not repeat" });
390
+ }
391
+ for (let index = 0; index < chain.length; index++) {
392
+ if (chain[index].parentReceiptDigest !== (digests[index + 1] ?? null)) {
393
+ context.addIssue({ code: "custom", message: "training receipt ancestry is incomplete or has been altered" });
394
+ }
395
+ }
396
+ });
397
+ export const agentProfileMetadataSchema = ownPropertyRecordSchema(z.unknown()).superRefine((metadata, context) => {
398
+ if (!Object.hasOwn(metadata, "training"))
399
+ return;
400
+ const result = agentProfileTrainingSchema.safeParse(metadata.training);
401
+ if (!result.success) {
402
+ for (const issue of result.error.issues) {
403
+ context.addIssue({ code: "custom", path: ["training", ...issue.path], message: issue.message });
404
+ }
405
+ }
406
+ });
325
407
  /**
326
408
  * The complete provider-neutral agent profile schema — the runtime validator for
327
409
  * the canonical {@link AgentProfile} TS contract. Kept structurally in lock-step
@@ -345,11 +427,27 @@ export const agentProfileSchema = z
345
427
  hooks: ownPropertyRecordSchema(z.array(agentProfileHookCommandSchema)).optional(),
346
428
  modes: ownPropertyRecordSchema(agentProfileModeSchema).optional(),
347
429
  confidential: agentProfileConfidentialSchema.optional(),
348
- metadata: ownPropertyRecordSchema(z.unknown()).optional(),
430
+ metadata: agentProfileMetadataSchema.optional(),
349
431
  extensions: ownPropertyRecordSchema(z.union([ownPropertyRecordSchema(z.unknown()), z.undefined()])).optional(),
350
432
  })
351
433
  .superRefine((profile, context) => {
352
434
  validateNestedRecordKeys(profile, context, [], new Set());
435
+ const training = agentProfileTrainingSchema.safeParse(profile.metadata?.training);
436
+ if (profile.model?.default?.startsWith(TRAINED_MODEL_PREFIX) && !training.success) {
437
+ context.addIssue({ code: "custom", path: ["metadata", "training"], message: "trained model requires a checkpoint receipt" });
438
+ }
439
+ const auxiliaryModels = [
440
+ profile.model?.small,
441
+ ...Object.values(profile.subagents ?? {}).map((agent) => agent.model),
442
+ ...Object.values(profile.modes ?? {}).map((mode) => mode.model),
443
+ ];
444
+ if (auxiliaryModels.some((model) => model?.startsWith(TRAINED_MODEL_PREFIX) &&
445
+ (!training.success || model !== training.data.receipt.checkpoint.routerModelId))) {
446
+ context.addIssue({ code: "custom", message: "trained auxiliary models require the same receipted checkpoint" });
447
+ }
448
+ if (training.success && profile.model?.default !== training.data.receipt.checkpoint.routerModelId) {
449
+ context.addIssue({ code: "custom", path: ["model", "default"], message: "trained profile model must equal the receipt's Router model" });
450
+ }
353
451
  });
354
452
  const encodedRecordKeyPattern = "^u(?:[0-9a-f]{4})*$";
355
453
  function isEncodedRecordKeyPropertyNames(value) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-interface",
3
- "version": "2.9.0",
3
+ "version": "2.10.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",