@kya-os/mcp-i-core 1.2.2-canary.33 → 1.2.2-canary.35

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.
@@ -376,7 +376,7 @@ export class AccessControlApiService {
376
376
  });
377
377
 
378
378
  const responseText = await httpResponse.text();
379
-
379
+
380
380
  // CRITICAL: Log raw response IMMEDIATELY before parsing/validation
381
381
  // This will help us debug validation failures
382
382
  console.error(`[AccessControl] 🔍 RAW API RESPONSE (before parsing):`, {
@@ -388,15 +388,17 @@ export class AccessControlApiService {
388
388
  responseTextPreview: responseText.substring(0, 500),
389
389
  fullResponseText: responseText, // Full response for debugging
390
390
  });
391
-
391
+
392
392
  const responseData = this.parseResponseJSON(httpResponse, responseText);
393
-
393
+
394
394
  // Log parsed response immediately after parsing
395
395
  console.error(`[AccessControl] 🔍 PARSED RESPONSE DATA:`, {
396
396
  correlationId,
397
397
  status: httpResponse.status,
398
398
  responseDataType: typeof responseData,
399
- responseDataKeys: Object.keys((responseData as Record<string, unknown>) || {}),
399
+ responseDataKeys: Object.keys(
400
+ (responseData as Record<string, unknown>) || {}
401
+ ),
400
402
  responseData: JSON.stringify(responseData, null, 2),
401
403
  });
402
404
 
@@ -509,31 +511,131 @@ export class AccessControlApiService {
509
511
  if (wrappedResponse.success !== undefined && wrappedResponse.data) {
510
512
  // Response is wrapped in { success, data }
511
513
  // Extract data and add success field if missing (for schema validation)
512
- const dataToValidate = wrappedResponse.data as Record<string, unknown>;
513
-
514
+ // CRITICAL: Ensure data is actually an object, not a string or other type
515
+ let dataToValidate: Record<string, unknown>;
516
+ if (typeof wrappedResponse.data === "string") {
517
+ // If data is a string, parse it (shouldn't happen but defensive)
518
+ try {
519
+ dataToValidate = JSON.parse(wrappedResponse.data) as Record<
520
+ string,
521
+ unknown
522
+ >;
523
+ } catch (parseError) {
524
+ throw new AgentShieldAPIError(
525
+ "invalid_response",
526
+ "Failed to parse response data",
527
+ {
528
+ parseError:
529
+ parseError instanceof Error
530
+ ? parseError.message
531
+ : String(parseError),
532
+ }
533
+ );
534
+ }
535
+ } else if (
536
+ typeof wrappedResponse.data === "object" &&
537
+ wrappedResponse.data !== null
538
+ ) {
539
+ dataToValidate = wrappedResponse.data as Record<string, unknown>;
540
+ } else {
541
+ throw new AgentShieldAPIError(
542
+ "invalid_response",
543
+ "Response data is not an object",
544
+ {
545
+ dataType: typeof wrappedResponse.data,
546
+ data: wrappedResponse.data,
547
+ }
548
+ );
549
+ }
550
+
514
551
  // CRITICAL: Log the actual data structure for debugging
515
552
  console.error(`[AccessControl] 🔍 DATA OBJECT STRUCTURE:`, {
516
553
  correlationId,
517
554
  dataKeys: Object.keys(dataToValidate),
518
- hasAccepted: 'accepted' in dataToValidate,
519
- hasRejected: 'rejected' in dataToValidate,
520
- hasOutcomes: 'outcomes' in dataToValidate,
521
- hasErrors: 'errors' in dataToValidate,
555
+ hasAccepted: "accepted" in dataToValidate,
556
+ hasRejected: "rejected" in dataToValidate,
557
+ hasOutcomes: "outcomes" in dataToValidate,
558
+ hasErrors: "errors" in dataToValidate,
522
559
  acceptedType: typeof dataToValidate.accepted,
560
+ acceptedValue: dataToValidate.accepted,
523
561
  rejectedType: typeof dataToValidate.rejected,
562
+ rejectedValue: dataToValidate.rejected,
524
563
  outcomesType: typeof dataToValidate.outcomes,
564
+ outcomesValue: dataToValidate.outcomes,
525
565
  errorsType: typeof dataToValidate.errors,
526
566
  errorsIsArray: Array.isArray(dataToValidate.errors),
527
567
  fullData: JSON.stringify(dataToValidate, null, 2),
528
568
  });
529
-
569
+
530
570
  // Ensure success field is present (required by schema)
531
571
  // wrappedResponse.success should be true since we checked it exists
532
- const dataWithSuccess = {
533
- ...dataToValidate,
534
- success: wrappedResponse.success === true, // Explicitly use wrapped success value
572
+ // CRITICAL: Explicitly construct the object to ensure all fields are present
573
+ // Don't rely on spread operator which might fail with Proxies or non-enumerable properties
574
+ const dataWithSuccess: Record<string, unknown> = {
575
+ success: wrappedResponse.success === true,
576
+ accepted: dataToValidate.accepted,
577
+ rejected: dataToValidate.rejected,
535
578
  };
536
579
 
580
+ // Add optional fields if present
581
+ if (
582
+ "outcomes" in dataToValidate &&
583
+ dataToValidate.outcomes !== undefined
584
+ ) {
585
+ dataWithSuccess.outcomes = dataToValidate.outcomes;
586
+ }
587
+ if ("errors" in dataToValidate && dataToValidate.errors !== undefined) {
588
+ dataWithSuccess.errors = dataToValidate.errors;
589
+ }
590
+
591
+ // CRITICAL: Log what we're validating
592
+ console.error(`[AccessControl] 🔍 VALIDATING DATA WITH SUCCESS:`, {
593
+ correlationId,
594
+ dataWithSuccessKeys: Object.keys(dataWithSuccess),
595
+ hasSuccess: "success" in dataWithSuccess,
596
+ successValue: dataWithSuccess.success,
597
+ hasAccepted: "accepted" in dataWithSuccess,
598
+ acceptedValue: dataWithSuccess.accepted,
599
+ hasRejected: "rejected" in dataWithSuccess,
600
+ rejectedValue: dataWithSuccess.rejected,
601
+ hasOutcomes: "outcomes" in dataWithSuccess,
602
+ outcomesValue: dataWithSuccess.outcomes,
603
+ fullDataWithSuccess: JSON.stringify(dataWithSuccess, null, 2),
604
+ });
605
+
606
+ // CRITICAL: Ensure all required fields are present before validation
607
+ if (
608
+ typeof dataWithSuccess.accepted !== "number" ||
609
+ typeof dataWithSuccess.rejected !== "number"
610
+ ) {
611
+ console.error(
612
+ `[AccessControl] ❌ MISSING REQUIRED FIELDS AFTER CONSTRUCTION:`,
613
+ {
614
+ correlationId,
615
+ hasAccepted: "accepted" in dataWithSuccess,
616
+ acceptedType: typeof dataWithSuccess.accepted,
617
+ acceptedValue: dataWithSuccess.accepted,
618
+ hasRejected: "rejected" in dataWithSuccess,
619
+ rejectedType: typeof dataWithSuccess.rejected,
620
+ rejectedValue: dataWithSuccess.rejected,
621
+ dataWithSuccessKeys: Object.keys(dataWithSuccess),
622
+ fullDataWithSuccess: JSON.stringify(dataWithSuccess, null, 2),
623
+ dataToValidateKeys: Object.keys(dataToValidate),
624
+ fullDataToValidate: JSON.stringify(dataToValidate, null, 2),
625
+ originalResponseData: JSON.stringify(responseData, null, 2),
626
+ }
627
+ );
628
+ throw new AgentShieldAPIError(
629
+ "invalid_response",
630
+ "Response data missing required fields (accepted/rejected)",
631
+ {
632
+ responseData,
633
+ dataToValidate,
634
+ dataWithSuccess,
635
+ }
636
+ );
637
+ }
638
+
537
639
  const dataParsed =
538
640
  proofSubmissionResponseSchema.safeParse(dataWithSuccess);
539
641
  if (dataParsed.success) {
@@ -561,6 +663,7 @@ export class AccessControlApiService {
561
663
  2000
562
664
  ),
563
665
  dataKeys: Object.keys(dataToValidate),
666
+ dataWithSuccessKeys: Object.keys(dataWithSuccess),
564
667
  originalResponse: JSON.stringify(responseData, null, 2).substring(
565
668
  0,
566
669
  2000
@@ -579,22 +682,25 @@ export class AccessControlApiService {
579
682
  `[AccessControl] Original wrapped response:`,
580
683
  JSON.stringify(responseData, null, 2)
581
684
  );
582
-
685
+
583
686
  // CRITICAL: Log each zod error individually for easier debugging
584
687
  console.error(
585
688
  `[AccessControl] ❌ ZOD VALIDATION FAILED - ${dataParsed.error.errors.length} error(s):`
586
689
  );
587
690
  dataParsed.error.errors.forEach((err, idx) => {
588
691
  const errorDetails: Record<string, unknown> = {
589
- path: err.path.join('.') || '(root)',
692
+ path: err.path.join(".") || "(root)",
590
693
  message: err.message,
591
694
  code: err.code,
592
695
  };
593
696
  // Only include properties that exist on specific error types
594
- if ('received' in err) errorDetails.received = err.received;
595
- if ('expected' in err) errorDetails.expected = err.expected;
596
- if ('input' in err) errorDetails.input = err.input;
597
- console.error(`[AccessControl] Error ${idx + 1}:`, errorDetails);
697
+ if ("received" in err) errorDetails.received = err.received;
698
+ if ("expected" in err) errorDetails.expected = err.expected;
699
+ if ("input" in err) errorDetails.input = err.input;
700
+ console.error(
701
+ `[AccessControl] Error ${idx + 1}:`,
702
+ JSON.stringify(errorDetails, null, 2)
703
+ );
598
704
  });
599
705
  console.error(
600
706
  `[AccessControl] ❌ Full ZOD errors JSON:`,
@@ -633,33 +739,30 @@ export class AccessControlApiService {
633
739
  // CRITICAL: Log to console.error with full details for debugging
634
740
  // This format matches test expectations: single call with message and error object
635
741
  // This log must include 'Response validation failed' in the message for test compatibility
636
- console.error(
637
- `[AccessControl] Response validation failed`,
638
- {
639
- zodErrors: parsed.error.errors,
640
- responseData: responseData,
641
- }
642
- );
742
+ console.error(`[AccessControl] Response validation failed`, {
743
+ zodErrors: parsed.error.errors,
744
+ responseData: responseData,
745
+ });
643
746
  // Additional detailed logging for debugging
644
747
  console.error(
645
748
  `[AccessControl] Response validation failed`,
646
749
  validationErrorLog
647
750
  );
648
-
751
+
649
752
  // CRITICAL: Log each zod error individually for easier debugging
650
753
  console.error(
651
754
  `[AccessControl] ❌ ZOD VALIDATION FAILED (direct) - ${parsed.error.errors.length} error(s):`
652
755
  );
653
756
  parsed.error.errors.forEach((err, idx) => {
654
757
  const errorDetails: Record<string, unknown> = {
655
- path: err.path.join('.') || '(root)',
758
+ path: err.path.join(".") || "(root)",
656
759
  message: err.message,
657
760
  code: err.code,
658
761
  };
659
762
  // Only include properties that exist on specific error types
660
- if ('received' in err) errorDetails.received = err.received;
661
- if ('expected' in err) errorDetails.expected = err.expected;
662
- if ('input' in err) errorDetails.input = err.input;
763
+ if ("received" in err) errorDetails.received = err.received;
764
+ if ("expected" in err) errorDetails.expected = err.expected;
765
+ if ("input" in err) errorDetails.input = err.input;
663
766
  console.error(`[AccessControl] Error ${idx + 1}:`, errorDetails);
664
767
  });
665
768
  console.error(