{"_id":"@ctchealth/plato-sdk","_rev":"28-9754f03096974f6148fdfec7089bd00f","name":"@ctchealth/plato-sdk","dist-tags":{"latest":"0.0.23"},"versions":{"0.0.1":{"name":"@ctchealth/plato-sdk","version":"0.0.1","_id":"@ctchealth/plato-sdk@0.0.1","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"}],"dist":{"shasum":"f26808d891579706fd51d327b8c24fba50227b62","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.1.tgz","fileCount":11,"integrity":"sha512-7kHydxo0BJc7SY5hM8oYYgCr+u2N9d6sfgVqPFMWGEZVflLcrNoghW48Os9J8rD4lJRqCblNmnp02PwzzFRsNw==","signatures":[{"sig":"MEYCIQCdbXghToEPygcDeTzctdxr2vyxkNgJEJ83Vrssk+DkwQIhAPYYx0q9XGdgVxT0KKD/MXOKE0+mAA2aegS/1+d49U+X","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":27433},"main":"./src/index.js","type":"commonjs","types":"./src/index.d.ts","gitHead":"7c7eebfacd318ca18653a5b2e2b2eaa67ef2de37","typings":"./src/index.d.ts","_npmUser":{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"},"_npmVersion":"9.2.0","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"18.19.1","dependencies":{"tslib":"^2.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.1_1762511015245_0.7448245465361494","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@ctchealth/plato-sdk","version":"0.0.2","_id":"@ctchealth/plato-sdk@0.0.2","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"}],"dist":{"shasum":"e812c22e3981e4fd5902d9675b7b063a8bf7af87","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.2.tgz","fileCount":11,"integrity":"sha512-sswVSGn4AsslOjA3KrR7O3k9lPN/UgG2cuz+jFeMvf2BmlVL/dtickx5Yn8srpSNyADe0PvBGbQ1az5bmosA4g==","signatures":[{"sig":"MEQCIDE7dJ5UMPPIyorjrs8PvsFHT8GsL1p/DKqHQutr+IULAiBY5UHVmBIX578im09vBaPYT1yuRwONeGPw7gT4E9+riw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":27433},"main":"./src/index.js","type":"commonjs","types":"./src/index.d.ts","gitHead":"3915219d55178be5d610b73296a9b2b026098f7c","typings":"./src/index.d.ts","_npmUser":{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"},"_npmVersion":"9.2.0","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"18.19.1","dependencies":{"tslib":"^2.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.2_1762512351704_0.5729344137529353","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@ctchealth/plato-sdk","version":"0.0.3","_id":"@ctchealth/plato-sdk@0.0.3","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"}],"dist":{"shasum":"f124ac18ee0422bb9b2126e2a49408b75e27d11b","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.3.tgz","fileCount":11,"integrity":"sha512-oTZXdfiUVPQxjTyoW2Y5ckFUI8Ma0INXKMP2ZpsNwNhQHe37ha7twfT9F74lTEByWas/PYT/DlvKX38P9eGuDg==","signatures":[{"sig":"MEQCIC3eZvafjgZiIYM1UbOZj1EWp0JRB7g8kz2ZPyKFzRThAiBt+QaaMoj0hEWfDOFU1NzUKYReKZA1EuRagcfLRnQoZg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":27462},"main":"./src/index.js","type":"commonjs","types":"./src/index.d.ts","gitHead":"3915219d55178be5d610b73296a9b2b026098f7c","typings":"./src/index.d.ts","_npmUser":{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"},"_npmVersion":"9.2.0","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"18.19.1","dependencies":{"tslib":"^2.3.0","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.3_1762525885188_0.38457433393827745","host":"s3://npm-registry-packages-npm-production"}},"0.0.4":{"name":"@ctchealth/plato-sdk","version":"0.0.4","_id":"@ctchealth/plato-sdk@0.0.4","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"}],"dist":{"shasum":"b6562d4b48b830c298d5434a67b1d3d2d16bede5","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.4.tgz","fileCount":11,"integrity":"sha512-JXOoGX4aaud+TA2iF40bcvuASCxs2idSDdj2UGB/0bkpDvjKto48NfHSkhoWUfrAFG7K41/06J3j50QrDyXBFg==","signatures":[{"sig":"MEUCIQDhgwDb2KvDyR0g0Z2bEY8mkgpBkEwpC7DtlVr9MGhR+wIgNo1lBQyZeQRji63cDU36zi5vZE0kXeT1M7mbvRPi8v4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":27462},"main":"./src/index.js","type":"commonjs","types":"./src/index.d.ts","gitHead":"3915219d55178be5d610b73296a9b2b026098f7c","typings":"./src/index.d.ts","_npmUser":{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"},"_npmVersion":"9.2.0","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"18.19.1","dependencies":{"tslib":"^2.3.0","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.4_1762529301660_0.1346105468351897","host":"s3://npm-registry-packages-npm-production"}},"0.0.5":{"name":"@ctchealth/plato-sdk","version":"0.0.5","_id":"@ctchealth/plato-sdk@0.0.5","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"}],"dist":{"shasum":"4ab163bc64a76f3736502a15a7df4ce59d179442","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.5.tgz","fileCount":11,"integrity":"sha512-DDMu/vaQeZKArlF1LFTEaemV3eW5yXDRcsZ1XNadNgItv0zwp+OumppZ3IsJRIcYWZlHQeY1S4ImJT42OJzEUA==","signatures":[{"sig":"MEQCIFozIE8hnHllpmq9E+2QBGX1UYASwFTyCmHNC50CzoUtAiAs3R6mDmHI8HGyISsqlmdmgZxVMnIV51r+PW1QbWBPuw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":28120},"main":"./src/index.js","type":"commonjs","types":"./src/index.d.ts","gitHead":"5c52f0bc96231c45ab2573fe519a6987b3f4108d","typings":"./src/index.d.ts","_npmUser":{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"},"_npmVersion":"9.2.0","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"18.19.1","dependencies":{"tslib":"^2.3.0","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.5_1763027909415_0.1496576991247598","host":"s3://npm-registry-packages-npm-production"}},"0.0.6":{"name":"@ctchealth/plato-sdk","version":"0.0.6","_id":"@ctchealth/plato-sdk@0.0.6","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"}],"dist":{"shasum":"ef14aab5805c1b0fb4b2a0aa33a94b7a868d02e0","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.6.tgz","fileCount":11,"integrity":"sha512-rvOLrrEvZwX8xlWLkFf4t8hmgtGdFkPt2Jc/JcoK8DNAiVymnYfwGFNLRnhQDQoeFUjdCo81+qkms5naSAJohA==","signatures":[{"sig":"MEYCIQD63zs+KJLTjllyhlpCiM4O3O4NOo6vAuOeLnkyOxPbRgIhAJISHZPQanuLqhRvJjjqq1WWByKiLQqswDDZCCELXJuJ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":30949},"main":"./src/index.js","type":"commonjs","types":"./src/index.d.ts","gitHead":"7c1aaa62d0e28123c9d3301962074471f937cef0","typings":"./src/index.d.ts","_npmUser":{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"},"_npmVersion":"9.2.0","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"18.19.1","dependencies":{"tslib":"^2.3.0","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.6_1763368796678_0.5904516655529313","host":"s3://npm-registry-packages-npm-production"}},"0.0.7":{"name":"@ctchealth/plato-sdk","version":"0.0.7","_id":"@ctchealth/plato-sdk@0.0.7","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"},{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"}],"dist":{"shasum":"51f830216565343a6544bdaee3c422948cccac7f","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.7.tgz","fileCount":11,"integrity":"sha512-vn+BFAYk/uxgmAig+llALhbnZBxeLF/wkUUFKu8RBIW0Yb9ugw3E2dNsSIKuajJoQrlSM4WfO2A8riGd2ri2SA==","signatures":[{"sig":"MEYCIQDc9vIHccdDCa6Xl48z6GUEZnRThO73uAuAoG1u6iaA7wIhAJ82tmbgnwiU+aYWbB2tPS+GYy9fyvLqPoGU0Hg7TbL5","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":32926},"main":"./src/index.js","type":"commonjs","types":"./src/index.d.ts","gitHead":"648e17a307e386f835526445bde10b4e28c852b8","typings":"./src/index.d.ts","_npmUser":{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"},"_npmVersion":"10.9.4","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"22.21.1","dependencies":{"tslib":"^2.3.0","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.7_1765302537633_0.9619477476839156","host":"s3://npm-registry-packages-npm-production"}},"0.0.8":{"name":"@ctchealth/plato-sdk","version":"0.0.8","_id":"@ctchealth/plato-sdk@0.0.8","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"},{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"},{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"}],"dist":{"shasum":"5b5d5d5b5a2d40b26886b33890ca0da21c6cec54","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.8.tgz","fileCount":10,"integrity":"sha512-JfPptbvbaZOYHCsyaSkpUmh7amZzelPHR06SWaiHFjrU3fR67hP6zFmZLkLttZaio3RWWqSGcvW7MgEr5fMd/w==","signatures":[{"sig":"MEYCIQDL5+vWbXFHmL7dYh21C6m1jl5snQ20Sf0VsCNpeYK4SgIhAPM39s7NRwlwzm/f5bd1q8fvFGMgOClZOMTgNkg/3lXR","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":28954},"main":"./src/index.js","type":"commonjs","types":"./../libs/plato-sdk/src/index.d.ts","gitHead":"6bbffcebcf43a20d07847d2409d0f7682a5d8ac7","typings":"./src/index.d.ts","_npmUser":{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"},"_npmVersion":"10.9.4","directories":{},"_nodeVersion":"22.21.1","dependencies":{"axios":"^1.7.9","tslib":"^2.3.0","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.8_1765553111513_0.8135556635471495","host":"s3://npm-registry-packages-npm-production"}},"0.0.9":{"name":"@ctchealth/plato-sdk","version":"0.0.9","_id":"@ctchealth/plato-sdk@0.0.9","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"},{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"},{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"}],"dist":{"shasum":"90f921f359445dfe3206cc4362cc82cb6377d91b","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.9.tgz","fileCount":11,"integrity":"sha512-w1EG5axFEO7AUrN/xJTjZBotF2uJ3AbDRkuWw/2RplfFUjfmVgbfIT+zgl+clyqNJmMPOv//HEn5TnZeBgPyQg==","signatures":[{"sig":"MEUCIQDKKt23IT+Q9c/xWOXILAmN0K1av/VXVecfDNGRQTL95QIgCfyV+x9Sw8QtVeY3LjL4aUYrAVh0W1zIoSQ6A68ineo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":27877},"main":"./src/index.js","type":"commonjs","gitHead":"6bbffcebcf43a20d07847d2409d0f7682a5d8ac7","typings":"./src/index.d.ts","_npmUser":{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"},"_npmVersion":"10.9.4","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"22.21.1","dependencies":{"axios":"^1.7.9","tslib":"^2.3.0","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.9_1765553648076_0.5430319496458444","host":"s3://npm-registry-packages-npm-production"}},"0.0.10":{"name":"@ctchealth/plato-sdk","version":"0.0.10","_id":"@ctchealth/plato-sdk@0.0.10","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"},{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"},{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"}],"dist":{"shasum":"973c6a91751924fcc87177d1a72805eab3d57747","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.10.tgz","fileCount":11,"integrity":"sha512-LZrtu6Qwh5PIULX2kRmZmHh1ok5dIBQVU7t6xRWaepoo665IomnCqYw0gVotuiydkjtMrAkt0bYVIO+EVpDYYQ==","signatures":[{"sig":"MEUCIAk0dw9aE7MgLhsXzB4gtMf2VlX/tTAf3n1Y+40zGxxyAiEAwnD3n9/b3FFNQx7X30zKy5PHTiB64rj/ZjxXxzbrUx8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":45479},"main":"./src/index.js","type":"commonjs","types":"./src/index.d.ts","gitHead":"fca9d335ab61323f6c30a2593dd8d2b8d306bad4","typings":"./src/index.d.ts","_npmUser":{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"},"_npmVersion":"10.9.4","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"22.21.1","dependencies":{"axios":"^1.7.9","tslib":"^2.3.0","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.10_1766584305058_0.3454861310777855","host":"s3://npm-registry-packages-npm-production"}},"0.0.11":{"name":"@ctchealth/plato-sdk","version":"0.0.11","_id":"@ctchealth/plato-sdk@0.0.11","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"},{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"},{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"}],"dist":{"shasum":"70b9ef1d764b51d27177eb56868b36f4c75b823c","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.11.tgz","fileCount":11,"integrity":"sha512-caxKkM2LpJCs2/ACq+HgjnzXuZ0UKtDu4J5PK344e3Qe5ozXgKSEaHXoXsNX4gXy5HNa7/zBPdWSq8tz+A6h7w==","signatures":[{"sig":"MEUCIQCCG4m/OfsyGzAFl+zs6cNiLr1tU7xWD8DZ8wOk30QeRgIgLFDDcyUMEkawD20bCKKeg5ep0HVQGf/Mw7R1ou75Jk4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50763},"main":"./src/index.js","type":"commonjs","types":"./src/index.d.ts","gitHead":"0208db2b8e42e407f3b40dcb76b44df0d36f857a","typings":"./src/index.d.ts","_npmUser":{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"},"_npmVersion":"10.9.4","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"22.21.1","dependencies":{"axios":"^1.7.9","tslib":"^2.3.0","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.11_1767012998602_0.6694587913781873","host":"s3://npm-registry-packages-npm-production"}},"0.0.12":{"name":"@ctchealth/plato-sdk","version":"0.0.12","_id":"@ctchealth/plato-sdk@0.0.12","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"},{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"},{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"}],"dist":{"shasum":"d11149427e5061be639a896e5f05fcca5ec44d04","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.12.tgz","fileCount":17,"integrity":"sha512-0egJVRzy+TVkciZQTNUYJagUHDucxBhbiFHAE3aoliOA8MfVDcUcIYyjtyVpCnJrf6BNRqAbVtlNOo9gmz8+EQ==","signatures":[{"sig":"MEQCICp3QoaXz8cBNyECqlsNKHoGf0HoF3CVheU61cc9yV5tAiAycPAVYyW4IUMcPAjRRZiDCQDrjhMGeMOnsJ/sqrZcJw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":69297},"main":"./src/index.js","type":"commonjs","types":"./src/index.d.ts","gitHead":"d42832de0c499cf86d2e910d1f975c492033c345","typings":"./src/index.d.ts","_npmUser":{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"},"_npmVersion":"10.9.4","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"22.21.1","dependencies":{"axios":"^1.7.9","tslib":"^2.3.0","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.12_1769525568703_0.010689512252940014","host":"s3://npm-registry-packages-npm-production"}},"0.0.13":{"name":"@ctchealth/plato-sdk","version":"0.0.13","_id":"@ctchealth/plato-sdk@0.0.13","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"},{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"},{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"}],"dist":{"shasum":"4eb20ee5c35e0fe5ffaa4a3b9c9e79fd98f8422a","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.13.tgz","fileCount":17,"integrity":"sha512-kR4sJfg9bR2B5omg/a2LCoi4sfwmDm9Ydk8lEpZMxvBKVY1nJ2HRXatO1zH1fdMPwb7srzW9yEUtZfZ1vuMb1Q==","signatures":[{"sig":"MEQCIQDUG4eWHDUYdk0rqIw2pTDXotpbkwFrv3tR6k2cdf6ScwIfQCl0kivLm9uPWyn+I3UCacrn7Eysq/kKB9k8hetX4g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":82578},"main":"./src/index.js","type":"commonjs","types":"./../../apps/plato-lx-api/libs/plato-sdk/src/index.d.ts","gitHead":"ba2cbd4871147e35ffb9ed8c51fe7360d8997d81","typings":"./src/index.d.ts","_npmUser":{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"},"_npmVersion":"10.9.4","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"22.21.1","dependencies":{"axios":"^1.7.9","tslib":"^2.3.0","pdf-lib":"^1.17.1","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.13_1770224210233_0.8296393629856107","host":"s3://npm-registry-packages-npm-production"}},"0.0.14":{"name":"@ctchealth/plato-sdk","version":"0.0.14","_id":"@ctchealth/plato-sdk@0.0.14","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"jorgectc","email":"jorge.orvium@ctchealth.ch"},{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"},{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"}],"dist":{"shasum":"e54d0c2d1a8fb63dd477d0551b004362b05ed045","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.14.tgz","fileCount":17,"integrity":"sha512-IR6dNyPDOdsA0WT2ztd7RM/fdGP4RLNnLP7YV6KuEzULzYgczQ1ZrhdaFzQIxZmTNmc3T95p0koyKvV7Gn8IIA==","signatures":[{"sig":"MEUCIGjN78c9kUMKQeJWY+MrX98/AX334tX8cqUmrOJ02GgyAiEAx+t8WBtBcu5+5NgItxTlm8lKQvqPCIs8ebFuA18voHo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":105582},"main":"./src/index.js","type":"commonjs","types":"./src/index.d.ts","gitHead":"6c5c078db64d0c7ad5ead7b9a6f0ff6953f28fd9","typings":"./src/index.d.ts","_npmUser":{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"},"_npmVersion":"10.9.4","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"22.21.1","dependencies":{"axios":"^1.7.9","tslib":"^2.3.0","pdf-lib":"^1.17.1","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.14_1770719005794_0.7463915010517814","host":"s3://npm-registry-packages-npm-production"}},"0.0.15":{"name":"@ctchealth/plato-sdk","version":"0.0.15","_id":"@ctchealth/plato-sdk@0.0.15","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"},{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"}],"dist":{"shasum":"48b22ac02a4dd1634d4022c92e0da8346f149be1","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.15.tgz","fileCount":16,"integrity":"sha512-Pw31MKlkrc9P/Dmc4erkfSn6CG1NXilY18CeRHHACaLyoUzEzmFLTEjhDH/fuTuopb34HKHRGGEKKlTmbgieRw==","signatures":[{"sig":"MEYCIQCc0hyRvvTA0n5Ovyb3c6QeVcDGSC4LFrvcmA4iqV9BLAIhAKVfNaNcAFzYqJ5HYRwTg23A144eqp5sM5m+gy1Cz3HY","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":74063},"main":"./src/index.js","type":"commonjs","types":"./../../apps/plato-lx-api/libs/plato-sdk/src/index.d.ts","gitHead":"5069fc776a60a9005db4e1ff92e83a9fda43d1fe","typings":"./src/index.d.ts","_npmUser":{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"},"_npmVersion":"10.9.4","directories":{},"_nodeVersion":"22.21.1","dependencies":{"axios":"^1.7.9","tslib":"^2.3.0","pdf-lib":"^1.17.1","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.15_1771493957918_0.8122995089547038","host":"s3://npm-registry-packages-npm-production"}},"0.0.16":{"name":"@ctchealth/plato-sdk","version":"0.0.16","_id":"@ctchealth/plato-sdk@0.0.16","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"},{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"}],"dist":{"shasum":"47a78feb105f6e6b179b0cd48293e6b03d7882da","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.16.tgz","fileCount":17,"integrity":"sha512-uRAgCC36HMgLGIB5mmDe2l9ddbO6yMTYwTQ3rHKu7Y6IArSyrgCYwArEbPpJ7mloHvMKKtWfmtfs5gszI1t84w==","signatures":[{"sig":"MEUCIB/S2Vl6uls8wVThYL8+khjA0R9g0g/zIX2z0PKB2UvPAiEAstfReK5FJIkdlWaNYf2Ebv7ZAImk8FX3lseQeQ2ja08=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":113751},"main":"./src/index.js","type":"commonjs","types":"./src/index.d.ts","gitHead":"9f633c589077854a2ae56fe7aef37922c4ec15bd","typings":"./src/index.d.ts","_npmUser":{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"},"_npmVersion":"10.9.4","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"22.21.1","dependencies":{"axios":"^1.7.9","tslib":"^2.3.0","pdf-lib":"^1.17.1","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.16_1771495466999_0.9933667676573195","host":"s3://npm-registry-packages-npm-production"}},"0.0.17":{"name":"@ctchealth/plato-sdk","version":"0.0.17","_id":"@ctchealth/plato-sdk@0.0.17","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"omardraz","email":"omar.draz@ctchealth.ch"},{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"},{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"}],"dist":{"shasum":"c2998f423aee3667638933db0ca1f47090ea8740","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.17.tgz","fileCount":13,"integrity":"sha512-ih8KCh61ODdrVkoYJ1yMw+M2GqO20H5U1ajVuWjsRymlEM97bj+p2a+jYhrB1MEW0KOAohoRjlhfBv1xDaEdAg==","signatures":[{"sig":"MEUCIQCiSsQRqyPcbHzv66RgfCkRsKtrSctF8Dfq7jbiqve+TAIgLSqDEXVcx2YYx/mPO05T6XMLLv9CGIGnYD5iwQMrHgI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":85376},"main":"./src/index.js","type":"commonjs","gitHead":"e6cafd55e336419bfb7e1caae0af08f0a3a63dc3","typings":"./src/index.d.ts","_npmUser":{"name":"omardraz","email":"omar.draz@ctchealth.ch"},"_npmVersion":"10.8.2","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"20.18.0","dependencies":{"axios":"^1.7.9","tslib":"^2.3.0","pdf-lib":"^1.17.1","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.17_1772022311290_0.6573288196435121","host":"s3://npm-registry-packages-npm-production"}},"0.0.18":{"name":"@ctchealth/plato-sdk","version":"0.0.18","_id":"@ctchealth/plato-sdk@0.0.18","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"omardraz","email":"omar.draz@ctchealth.ch"},{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"},{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"}],"dist":{"shasum":"d41851975f11c95999f23c8bd3f6445667157993","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.18.tgz","fileCount":17,"integrity":"sha512-j7DXDzdmjQ3PH7SRlJGJfoisDjXT2dLtCl04qb3w4rwcvZ7p3pwT6Z0GNxJpI2/UzbSbo+bIj3GAjdrjQ0VDzQ==","signatures":[{"sig":"MEUCIQDKqDHZk/BMI9DkIRNR+PkO5LtVNA56pUSPhW+y0BjNtgIgPrwppna0sEadQ20holDZ8RTHtf6zo+U3b+sXuZaSwcA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":118794},"main":"./src/index.js","type":"commonjs","types":"./src/index.d.ts","gitHead":"fb2f17b8509cd638c5034a0767b3806d36aa5c7e","typings":"./src/index.d.ts","_npmUser":{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"},"_npmVersion":"10.9.4","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"22.21.1","dependencies":{"axios":"^1.7.9","tslib":"^2.3.0","pdf-lib":"^1.17.1","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.18_1772464683161_0.8026013586717573","host":"s3://npm-registry-packages-npm-production"}},"0.0.19":{"name":"@ctchealth/plato-sdk","version":"0.0.19","_id":"@ctchealth/plato-sdk@0.0.19","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"omardraz","email":"omar.draz@ctchealth.ch"},{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"},{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"}],"dist":{"shasum":"2b9ccc480c1738194fc3e10623b6d3a1bfb5cdcf","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.19.tgz","fileCount":13,"integrity":"sha512-FHrOPuwOar9S2ZjvrdO3p4tgrImhzJdBS+cWFNDhDYrbhQmPlBAdZ615gV8kztXG8wJgeCirtPdgu0uDSsIsCA==","signatures":[{"sig":"MEYCIQCqtHoYqTiDf7Patoke3890UtyOtSHLo/KJhWYliAFoaQIhAN3vpVwh5ElzoNHmhF5qzx0Gi1u5Px1HR6BP10gpg7g0","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":85493},"main":"./src/index.js","type":"commonjs","gitHead":"69a646dd11f577790afa65c19efdf336937c0927","typings":"./src/index.d.ts","_npmUser":{"name":"omardraz","email":"omar.draz@ctchealth.ch"},"_npmVersion":"10.8.2","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"20.18.0","dependencies":{"axios":"^1.7.9","tslib":"^2.3.0","pdf-lib":"^1.17.1","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.19_1775219465605_0.16916992202765102","host":"s3://npm-registry-packages-npm-production"}},"0.0.20":{"name":"@ctchealth/plato-sdk","version":"0.0.20","_id":"@ctchealth/plato-sdk@0.0.20","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"omardraz","email":"omar.draz@ctchealth.ch"},{"name":"ali-shaaban-ctchealth","email":"ali.shaaban@ctchealth.ch"},{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"},{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"}],"dist":{"shasum":"439c97bdfb958d57c0c3a84b7a614a2252c15cf1","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.20.tgz","fileCount":17,"integrity":"sha512-d08NNf9LrUlEMkTExyeR76jLbDrqzeDxgmECDMei62HKFnOH/OVTLisdrTEMwHjQVy4SrZSSVYGo3uXRgZnEng==","signatures":[{"sig":"MEYCIQD1vos0j7iKRTjMag/LAjopD26WakJgxgDgVHX7ekMvXwIhAO2iotpyCDCGERiMKEqfSxzILO5E6CYCQyQJhhFIeRmF","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":118995},"main":"./src/index.js","type":"commonjs","types":"./src/index.d.ts","gitHead":"9e16f5da01779696c666a61ec32017db4ec8ac14","typings":"./src/index.d.ts","_npmUser":{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"},"_npmVersion":"10.9.4","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"22.21.1","dependencies":{"axios":"^1.7.9","tslib":"^2.3.0","pdf-lib":"^1.17.1","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.20_1778078350058_0.6301818731718587","host":"s3://npm-registry-packages-npm-production"}},"0.0.21":{"name":"@ctchealth/plato-sdk","version":"0.0.21","_id":"@ctchealth/plato-sdk@0.0.21","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"omardraz","email":"omar.draz@ctchealth.ch"},{"name":"ali-shaaban-ctchealth","email":"ali.shaaban@ctchealth.ch"},{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"},{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"}],"dist":{"shasum":"e382a7e1bccac6fdf68f857dcb5e6165748440e0","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.21.tgz","fileCount":17,"integrity":"sha512-rd4w7+jm+sZZJsBRYPBtyDaB2Dt4BJg3+K+n90ReXaMbmaeTQvaer6ZxfJKvUVDGTdrFjOgsMzZi6wjbJHOzsw==","signatures":[{"sig":"MEYCIQCgHq667IuuwIQNSd2rjo/kHon7GaJdoPlxeGqSBGCZ3wIhAIWUKB7taQd6abmmBSXGuGTrt9QGYRYYJBG3gedR53LB","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":128499},"main":"./src/index.js","type":"commonjs","types":"./src/index.d.ts","gitHead":"6b78aa889356ec751d175682cce6b72885070c53","typings":"./src/index.d.ts","_npmUser":{"name":"ali-shaaban-ctchealth","email":"ali.shaaban@ctchealth.ch"},"_npmVersion":"10.9.7","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"axios":"^1.7.9","tslib":"^2.3.0","pdf-lib":"^1.17.1","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.21_1780666768698_0.9983962802754838","host":"s3://npm-registry-packages-npm-production"}},"0.0.22":{"name":"@ctchealth/plato-sdk","version":"0.0.22","_id":"@ctchealth/plato-sdk@0.0.22","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"omardraz","email":"omar.draz@ctchealth.ch"},{"name":"ali-shaaban-ctchealth","email":"ali.shaaban@ctchealth.ch"},{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"},{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"}],"dist":{"shasum":"9acffe85d033ef3d384313684747a3f612f19201","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.22.tgz","fileCount":17,"integrity":"sha512-sHgFJvh1UOqaeKJtCySxZMwGCJAfSKWgVnUuRPnxRRjO0xq3ifVAW1f32MB1CcXLwKv0wVEDBtavYTN2Kk6k5w==","signatures":[{"sig":"MEYCIQCLF5h0SQ/5QSKpibk1wRr5ec9izqPZPyhooeHSroDqAQIhANYawyPBixAxEchEJFV57d+hS0vZcqoN/Q9czycN0NZV","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":129178},"main":"./src/index.js","type":"commonjs","types":"./src/index.d.ts","gitHead":"23c888f0c8abde663114528622b90f0fb4a0372a","typings":"./src/index.d.ts","_npmUser":{"name":"ali-shaaban-ctchealth","email":"ali.shaaban@ctchealth.ch"},"_npmVersion":"10.9.7","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","directories":{},"_nodeVersion":"22.22.2","dependencies":{"axios":"^1.7.9","tslib":"^2.3.0","pdf-lib":"^1.17.1","@vapi-ai/web":"2.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/plato-sdk_0.0.22_1781097755903_0.3395059686929358","host":"s3://npm-registry-packages-npm-production"}},"0.0.23":{"name":"@ctchealth/plato-sdk","version":"0.0.23","dependencies":{"tslib":"^2.3.0","@vapi-ai/web":"2.1.8","axios":"^1.7.9","pdf-lib":"^1.17.1"},"type":"commonjs","main":"./src/index.js","typings":"./src/index.d.ts","publishConfig":{"access":"public"},"types":"./src/index.d.ts","_id":"@ctchealth/plato-sdk@0.0.23","gitHead":"a0472463bdbaa68feb9c03adf2740c9da5c55d01","description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","_nodeVersion":"22.22.2","_npmVersion":"10.9.7","dist":{"integrity":"sha512-nr3ELrWyLhtK7AGvGg2/nPjiklN3j13pIHs43HjLZcLvALtOrTVu01sAXdxAi3I167z6cazSg3etQpQGQ7xcGw==","shasum":"6bee691f11b0b212281928af84a2f47f4b5565a1","tarball":"https://registry.npmjs.org/@ctchealth/plato-sdk/-/plato-sdk-0.0.23.tgz","fileCount":17,"unpackedSize":133905,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFhropenKbKY40+8idu5pCW6iIv2epFpQUasHawiQ47FAiANr26+dvuM60roKqYMEzQ0WYMer86X6J2JIt9Y8GjRjw=="}]},"_npmUser":{"name":"ali-shaaban-ctchealth","email":"ali.shaaban@ctchealth.ch"},"directories":{},"maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"omardraz","email":"omar.draz@ctchealth.ch"},{"name":"ali-shaaban-ctchealth","email":"ali.shaaban@ctchealth.ch"},{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"},{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/plato-sdk_0.0.23_1781538514889_0.8060350034010646"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-07T10:23:35.144Z","modified":"2026-06-15T15:48:35.278Z","0.0.1":"2025-11-07T10:23:35.427Z","0.0.2":"2025-11-07T10:45:51.907Z","0.0.3":"2025-11-07T14:31:25.399Z","0.0.4":"2025-11-07T15:28:21.881Z","0.0.5":"2025-11-13T09:58:29.629Z","0.0.6":"2025-11-17T08:39:56.868Z","0.0.7":"2025-12-09T17:48:57.778Z","0.0.8":"2025-12-12T15:25:11.650Z","0.0.9":"2025-12-12T15:34:08.212Z","0.0.10":"2025-12-24T13:51:45.200Z","0.0.11":"2025-12-29T12:56:38.760Z","0.0.12":"2026-01-27T14:52:48.855Z","0.0.13":"2026-02-04T16:56:50.404Z","0.0.14":"2026-02-10T10:23:25.955Z","0.0.15":"2026-02-19T09:39:18.048Z","0.0.16":"2026-02-19T10:04:27.132Z","0.0.17":"2026-02-25T12:25:11.439Z","0.0.18":"2026-03-02T15:18:03.328Z","0.0.19":"2026-04-03T12:31:05.750Z","0.0.20":"2026-05-06T14:39:10.203Z","0.0.21":"2026-06-05T13:39:28.849Z","0.0.22":"2026-06-10T13:22:36.040Z","0.0.23":"2026-06-15T15:48:35.063Z"},"description":"A TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.","maintainers":[{"name":"manuelctchealth","email":"manuel.martin.marquez@ctchealth.ch"},{"name":"torben-guijarro-heeb-ctchealth","email":"torben.guijarro.heeb@ctchealth.ch"},{"name":"tech_ctchealth","email":"tech@ctchealth.ch"},{"name":"omardraz","email":"omar.draz@ctchealth.ch"},{"name":"ali-shaaban-ctchealth","email":"ali.shaaban@ctchealth.ch"},{"name":"mohamed-battawy-ctchealth","email":"mohamed.battawy@ctchealth.ch"},{"name":"muayad-mahmoud-ctchealth","email":"muayad.mahmoud@ctchealth.ch"}],"readme":"# Plato SDK\n\nA TypeScript SDK for interacting with the Plato API to create and manage AI-powered medical training simulations.\n\n## Overview\n\nThe Plato SDK provides a simple and type-safe way to integrate with the Plato platform, allowing you to create medical training simulations with AI personas and manage voice-based interactions.\n\n## Authentication\n\nAll API requests require authentication via a client token. Pass a pre-signed JWT token as `jwtToken` when initializing the client. This is sent as the `x-client-token` header on every request.\n\n## Features\n\n- Create AI personas with customizable professional profiles and personalities\n- Real-time voice interactions with AI assistants\n- Comprehensive event system for call management\n- Type-safe API with full TypeScript support\n- Medical training simulation configuration\n- Simulation persistence across page reloads\n\n## Installation\n\n```bash\nnpm install plato-sdk\n```\n\n## Quick Start\n\n```typescript\nimport { PlatoApiClient, AvatarLanguage } from 'plato-sdk';\n\n// Initialize the client\nconst client = new PlatoApiClient({\n  baseUrl: 'https://your-plato-api.com',\n  jwtToken: 'your-jwt-token',\n  publicKey: 'your-public-key',\n});\n\n// Get available assistant images\nconst images = await client.getAssistantImages();\n\n// Create a simulation\nconst simulation = await client.createSimulation({\n  persona: {\n    professionalProfile: {\n      location: 'City Hospital, New York',\n      practiceSettings: 'Outpatient Clinic',\n      yearOfExperience: 12,\n      specialityAndDepartment: 'Cardiology',\n    },\n    segment: SegmentType.CostConsciousPrescriber,\n    assistantGender: AssistantVoiceGender.Male,\n    name: 'Dr Vegapunk',\n    personalityAndBehaviour: {\n      riskTolerance: 40,\n      researchOrientation: 70,\n      recognitionNeed: 60,\n      brandLoyalty: 55,\n      patientEmpathy: 80,\n    },\n    context: {\n      subSpecialityOrTherapyFocus: 'Hypertension management',\n      typicalPatientMix: 'Elderly with comorbidities',\n      keyClinicalDrivers: 'Reducing cardiovascular risk',\n    },\n  },\n  product: {\n    name: 'Ibuprofen 1000mg',\n    description:\n      'A nonsteroidal anti-inflammatory drug used to reduce pain, inflammation, and fever',\n  },\n  pdfSlideId: 'pdf-slide-id', // optional, ID from uploadPdfSlides()\n  scenario: 'Discussing treatment options for an elderly patient with chronic arthritis',\n  objectives:\n    'Demonstrate efficacy of Ibuprofen in pain management Highlight safety profile and contraindications Encourage patient adherence',\n  anticipatedObjections:\n    'Concerns about gastrointestinal side effects Preference for lower-cost generic alternatives Potential interactions with other medications',\n  imageId: images[0]._id,\n  avatarLanguage: AvatarLanguage.English,\n});\n\n// Check the simulation status - If simulation creation phase is equals to FINISHED, the simulation is ready to use\n// If the simulation creation phase is ERROR the simulation creation failed and you need to retry creating a new one\n// tip: you can also check the simulation status periodically using a polling mechanism\nconst status = await client.getSimulationStatus(simulation.simulationId);\n\n// Start a voice call\nconst call = await client.startCall(simulation.simulationId);\n\n// Listen to call events\ncall.on('call-start', () => {\n  console.log('Call started');\n});\n\ncall.on('message', message => {\n  console.log('Message received:', message.transcript);\n});\n\ncall.on('call-end', () => {\n  console.log('Call ended - processing feedback...');\n});\n\n// Automatically receive post-call feedback when ready\ncall.on('call-details-ready', callDetails => {\n  console.log('Call Summary:', callDetails.summary);\n  console.log('Score:', callDetails.score);\n  console.log('Strengths:', callDetails.strengths);\n  console.log('Areas to improve:', callDetails.weaknesses);\n});\n\n// Stop the call when done\ncall.stopCall();\n```\n\n## API Reference\n\n### PlatoApiClient\n\nThe main class for interacting with the Plato API.\n\n#### Constructor\n\n```typescript\nnew PlatoApiClient(config: ApiClientConfig)\n```\n\n**Parameters:**\n\n- `config.baseUrl` (string, required): The base URL of the Plato API\n- `config.jwtToken` (string, required): A pre-signed JWT token sent as the `x-client-token` header on every request\n- `config.publicKey` (string, required): Your public key for voice call functionality\n\n**Example:**\n\n```typescript\nconst client = new PlatoApiClient({\n  baseUrl: 'https://your-plato-api.com',\n  jwtToken: 'eyJhbGciOiJSUzI1NiIs...',\n  publicKey: 'your-public-key',\n});\n```\n\n#### Methods\n\n##### setJwtToken(jwtToken: string)\n\nUpdates the JWT token for all subsequent requests. Use this when the token is refreshed or when switching user context.\n\n```typescript\nclient.setJwtToken('new-jwt-token');\n```\n\n##### clearJwtToken()\n\nRemoves the JWT token from subsequent requests.\n\n```typescript\nclient.clearJwtToken();\n```\n\n##### createSimulation(params: CreateSimulationDto)\n\nCreates a new medical training simulation. It may take a few minutes for the simulation to be ready for use.\n\n**Returns:** `Promise<{ simulationId: string, phase: CreationPhase }>`\n\n**Learning mode (`isLearning`):** Pass `isLearning: true` and their calls are excluded from `getRecommendations()` and have no post call. Defaults to `false`.\n\n##### startCall(simulationId: string)\n\nStarts a voice call with the AI persona for the specified simulation.\n\n**Returns:** Object with:\n\n- `stopCall()`: Function to end the call\n- `callId`: Unique identifier for the call\n- `notifySlideChange(slideNumber: number)`: Inform the assistant which PDF slide the user is currently viewing (see [Slide-Aware Conversations](#slide-aware-conversations))\n- `on<K>(event: K, listener: CallEventListener<K>)`: Subscribe to call events\n- `off<K>(event: K, listener: CallEventListener<K>)`: Unsubscribe from call events\n\n##### getCallDetails(callId: string)\n\nRetrieves detailed information about a completed call, including transcript, summary, recording URL, ratings, and evaluation metrics.\n\n**Parameters:**\n\n- `callId` (string): The MongoDB `_id` of the call\n\n**Returns:** `Promise<CallDTO>` — An object containing:\n\n- `_id`: MongoDB ID of the call\n- `summary`: Summary of the conversation\n- `transcript`: Full transcript of the call\n- `recordingUrl`: URL to access the call recording\n- `rating`: User-provided rating (0-5)\n- `successEvaluation`: Boolean indicating if the call was successful\n- `score`: Overall score for the call\n- `strengths`: Array of identified strengths\n- `weaknesses`: Array of identified weaknesses\n- `metric1`, `metric2`, `metric3`: Evaluation metric names\n- `metric1Value`, `metric2Value`, `metric3Value`: Values for each metric\n- `createdAt`: Timestamp when the call was created\n- `endedAt`: Timestamp when the call ended\n- `callDurationMs`: Duration of the call in milliseconds\n- And other call-related fields\n\n**Example:**\n\n```typescript\n// After a call has ended, retrieve its details\nconst callDetails = await client.getCallDetails(call._id);\nconsole.log('Call Summary:', callDetails.summary);\n```\n\n##### deleteCall(callId: string)\n\nDeletes a single call and all associated data including messages, recommendations, and the S3 recording. Only the owner of the call (the rep who made it) can delete it.\n\n**Parameters:**\n\n- `callId` (string): The MongoDB `_id` of the call to delete\n\n**Returns:** `Promise<void>`\n\n**Example:**\n\n```typescript\nawait client.deleteCall('507f1f77bcf86cd799439011');\n```\n\n**Note:** This action is irreversible. The call, its transcript, messages, recording, and any recommendations generated from it will be permanently removed.\n\n##### getCallRecordings(queryParams: SimulationRecordingsQueryDto)\n\nRetrieves a paginated list of call recordings for the authenticated user.\n\n**Parameters:**\n\n- `queryParams` (SimulationRecordingsQueryDto): Query parameters for filtering and pagination\n  - `limit` (optional): Number of recordings per page (`5`, `10`, or `25`)\n  - `page` (optional): Page number for pagination\n  - `sort` (optional): Sort order (`'asc'` or `'desc'`)\n\n**Returns:** `Promise<SimulationRecordingsDto[]>` — An array of recording objects, each containing:\n\n- `_id`: MongoDB ID of the call\n- `createdAt`: Timestamp when the call was created\n- `recordingStatus`: Status of the recording (`'STARTED'`, `'PROCESSING'`, `'FINISHED'`, or `'FAILED'`)\n\n**Example:**\n\n```typescript\n// Get the 10 most recent call recordings\nconst recordings = await client.getCallRecordings({\n  limit: 10,\n  page: 1,\n  sort: 'desc',\n});\n\nrecordings.forEach(recording => {\n  console.log(`Call ${recording._id} - Status: ${recording.recordingStatus}`);\n});\n```\n\n##### getCallRecording(callId: string)\n\nRetrieves the recording URL for a specific call.\n\n**Parameters:**\n\n- `callId` (string): The MongoDB `_id` of the call\n\n**Returns:** `Promise<string>` — The URL to access the call recording\n\n**Example:**\n\n```typescript\n// Get the recording URL for a specific call\nconst recordingUrl = await client.getCallRecording(call._id);\nconsole.log('Recording URL:', recordingUrl);\n```\n\n##### uploadPdfSlides(file: File | Blob)\n\nUploads a PDF file for slide analysis. The file will be uploaded to S3 and analyzed asynchronously.\n\n**Parameters:**\n\n- `file` (File | Blob): The PDF file to upload\n\n**Returns:** `Promise<string>` — The MongoDB ID of the created PDF record, which can be used to track the analysis status.\n\n**Limitations:**\n\n- **Latin-only file names:** The PDF file name must contain only Latin characters. Non-latin characters in the file name are not supported.\n- **Maximum 100 pages:** PDF files cannot exceed 100 pages.\n- **No duplicate content:** Uploading a PDF with identical content that was already uploaded by your organization throws an error. Duplicates are detected based on file content, not file name, and are scoped per organization.\n\n**Example:**\n\n```typescript\nimport { PdfAlreadyExistsError } from 'plato-sdk';\n\nconst fileInput = document.querySelector('input[type=\"file\"]') as HTMLInputElement;\nconst file = fileInput.files?.[0];\n\nif (file) {\n  try {\n    const pdfId = await client.uploadPdfSlides(file);\n    console.log('PDF uploaded, ID:', pdfId);\n    // Poll status until analysis completes\n  } catch (error) {\n    if (error instanceof PdfAlreadyExistsError) {\n      // Inform the user this PDF already exists in their organization\n      console.error(\n        'This PDF has already been uploaded by your organization. PDF ID:',\n        error.pdfId\n      );\n    } else {\n      console.error('Upload failed:', error.message);\n    }\n  }\n}\n```\n\n##### getSlidesAnalysis(queryParams: PdfSlidesAnalysisQueryDto)\n\nRetrieves a paginated and sorted list of PDF slide analysis records.\n\n**Parameters:**\n\n- `queryParams` (PdfSlidesAnalysisQueryDto):\n  - `limit` (optional): Number of records per page\n  - `page` (optional): Page number\n  - `sort` (optional): Sort order (`'asc'` or `'desc'`)\n  - `sortBy` (optional): Field to sort by (`'createdAt'`, `'originalFilename'`, or `'totalSlides'`)\n\n**Returns:** `Promise<PdfSlidesDto[]>`\n\n**Example:**\n\n```typescript\nconst analysisList = await client.getSlidesAnalysis({\n  limit: 10,\n  page: 0,\n  sort: 'desc',\n  sortBy: 'createdAt',\n});\n```\n\n##### getSlideAnalysis(id: string)\n\nRetrieves the detailed analysis data for a specific PDF slide record, including the overview and individual slide analysis.\n\n**Parameters:**\n\n- `id` (string): The unique ID of the PDF slide record\n\n**Returns:** `Promise<PdfSlideDto>`\n\n**Example:**\n\n```typescript\nconst details = await client.getSlideAnalysis('pdf-slide-id');\nconsole.log('Lesson Overview:', details.lessonOverview);\n```\n\n##### deleteSlideAnalysis(id: string)\n\nDeletes a PDF slide analysis record from the database and removes the corresponding file from S3 storage.\n\n**Parameters:**\n\n- `id` (string): The unique ID of the PDF slide record to delete\n\n**Returns:** `Promise<void>`\n\n**Example:**\n\n```typescript\nawait client.deleteSlideAnalysis('pdf-slide-id');\nconsole.log('Analysis deleted successfully');\n```\n\n##### checkPdfStatus(id: string)\n\nChecks the current processing status of a PDF slide analysis. Use this to monitor the progress of PDF analysis workflows.\n\n**Parameters:**\n\n- `id` (string): The unique ID of the PDF slide record\n\n**Returns:** `Promise<{ status: PdfSlidesStatus }>` — An object containing the current status\n\n**Available Status Values:**\n\n- `started` - PDF uploaded and record created\n- `processing` - Receiving batches of analyzed slides\n- `overview` - All slides analyzed, generating lesson overview\n- `completed` - Analysis complete and ready to view\n- `failed` - Analysis failed (currently not implemented)\n\n**Example:**\n\n```typescript\n// Check PDF analysis status\nconst { status } = await client.checkPdfStatus('pdf-slide-id');\n\nconsole.log('Current status:', status);\n```\n\n**Typical Workflow:**\n\n```typescript\n// 1. Upload PDF and get the ID immediately\nconst pdfId = await client.uploadPdfSlides(file);\nconsole.log('PDF uploaded with ID:', pdfId);\n\n// 2. Poll status until complete\nconst checkStatus = async () => {\n  const { status } = await client.checkPdfStatus(pdfId);\n\n  switch (status) {\n    case 'pending':\n      console.log('Waiting for upload confirmation...');\n      break;\n    case 'started':\n      console.log('Upload confirmed, starting analysis...');\n      break;\n    case 'processing':\n      console.log('Analyzing slides...');\n      break;\n    case 'overview':\n      console.log('Generating lesson overview...');\n      break;\n    case 'completed':\n      console.log('Analysis complete!');\n      // Now fetch the full analysis\n      const analysis = await client.getSlideAnalysis(pdfId);\n      console.log('Lesson overview:', analysis.lessonOverview);\n      return; // Stop polling\n    case 'failed':\n      console.log('Analysis failed');\n      return; // Stop polling\n  }\n\n  // Check again in 3 seconds\n  setTimeout(checkStatus, 3000);\n};\n\ncheckStatus();\n```\n\n##### getAssistantImages()\n\nRetrieves all available assistant images that can be used when creating a simulation.\n\n**Returns:** `Promise<AssistantImageDto[]>` — An array of assistant image objects, each containing:\n\n- `_id`: Unique identifier for the image\n- `imageUrl`: URL of the assistant image\n\n**Example:**\n\n```typescript\n// Get all available assistant images\nconst images = await client.getAssistantImages();\n```\n\n##### deleteSimulation(simulationId: string)\n\nDeletes a simulation and all associated data. This permanently removes the simulation, all its call records, and excludes it from future recommendations analysis.\n\n**Parameters:**\n\n- `simulationId` (string): The MongoDB `_id` of the simulation to delete\n\n**Returns:** `Promise<void>`\n\n**Example:**\n\n```typescript\nawait client.deleteSimulation('507f1f77bcf86cd799439011');\n```\n\n**Note:** This action is irreversible. All calls and recordings linked to the simulation will also be deleted.\n\n##### getRecommendations()\n\nRetrieves recommendations based on the user's recent call performance. Analyzes the 5 most recent calls using a sliding window of 3 calls to identify patterns and provide actionable insights. Calls shorter than 2 minutes are excluded from analysis, as are calls made against learning-mode simulations (`isLearning: true`). No new recommendations are generated if fewer than 3 eligible calls are available.\n\n**Returns:** `Promise<RecommendationsResponseDto>` — An object containing:\n\n- `recommendations`: Array of recommendation objects, each with:\n  - `title`: Brief title of the recommendation\n  - `description`: Detailed, actionable description\n  - `priority`: Priority level (`'high'`, `'medium'`, or `'low'`)\n- `strengths`: Array of identified strengths, each with:\n  - `strength`: Description of the strength\n  - `frequency`: Number of calls where this strength appeared\n- `improvementAreas`: Array of areas needing improvement, each with:\n  - `area`: Description of the improvement area\n  - `frequency`: Number of calls where this weakness appeared\n- `summary`: A 2-3 sentence overall summary of performance trends\n- `callsAnalyzed`: Number of calls that were analyzed\n- `generatedAt`: Timestamp when the recommendations were generated\n\n**Example:**\n\n```typescript\n// Get personalized recommendations based on call history\nconst recommendations = await client.getRecommendations();\n\nconsole.log(`Analyzed ${recommendations.callsAnalyzed} calls`);\nconsole.log('Summary:', recommendations.summary);\n\n// Display high-priority recommendations\nrecommendations.recommendations\n  .filter(rec => rec.priority === 'high')\n  .forEach(rec => {\n    console.log(`[HIGH] ${rec.title}: ${rec.description}`);\n  });\n\n// Show recurring strengths\nrecommendations.strengths.forEach(s => {\n  console.log(`Strength (${s.frequency} calls): ${s.strength}`);\n});\n\n// Show areas for improvement\nrecommendations.improvementAreas.forEach(area => {\n  console.log(`Needs work (${area.frequency} calls): ${area.area}`);\n});\n```\n\n**Note:** This method requires the user to have at least one completed call. If no calls are found, a `BadRequestException` will be thrown.\n\n## Checking Simulation Status\n\nYou can check the current phase/status of a simulation using the `checkSimulationStatus` method. This is useful for polling the simulation creation process until it is ready or has failed.\n\n```typescript\nconst status = await client.checkSimulationStatus(simulation.simulationId);\nconsole.log('Current phase:', status.phase); // e.g., 'FINISHED', 'ERROR', etc.\n```\n\n- **Returns:** `{ phase: CreationPhase }` — The current phase of the simulation creation process.\n- **Typical usage:** Poll this method until the phase is `FINISHED` or `ERROR` before starting a call.\n\n## Simulation Persistence\n\nSimulations are persisted server-side and can be recovered after page reloads. Store the simulation ID client-side (e.g., localStorage) for quick recovery.\n\n### getSimulationDetails(simulationId: string)\n\nRetrieves detailed information about a simulation, including its original configuration.\n\n**Returns:** `Promise<SimulationDetailsDto>` containing:\n\n- `simulationId`: MongoDB ID\n- `phase`: Current creation phase\n- `assistantId`: The assistant ID (available after creation)\n- `configuration`: Original `CreateSimulationDto`\n- `simulationBriefing`: Optional `SimulationBriefingDto` with persona description, scenario context, and training objectives (available after creation phase reaches `FINISHED`)\n- `createdAt`, `updatedAt`: Timestamps\n\n**Example:**\n\n```typescript\n// Store simulation ID after creation\nconst simulation = await client.createSimulation(config);\nlocalStorage.setItem('plato_simulation_id', simulation.simulationId);\n\n// Recover simulation on page reload\nconst simulationId = localStorage.getItem('plato_simulation_id');\nif (simulationId) {\n  const details = await client.getSimulationDetails(simulationId);\n\n  if (details.phase !== CreationPhase.ERROR) {\n    // Resume polling if still in progress\n    if (details.phase !== CreationPhase.FINISHED) {\n      startPolling(details.simulationId);\n    }\n\n    // Access simulation briefing when available\n    if (details.simulationBriefing) {\n      console.log('Objective:', details.simulationBriefing.objectiveTag);\n      console.log('Persona:', details.simulationBriefing.personaDescription.summary);\n      console.log('Scenario:', details.simulationBriefing.scenarioContext.summary);\n      console.log('Training Goals:', details.simulationBriefing.trainingObjective.keyObjectives);\n    }\n  } else {\n    localStorage.removeItem('plato_simulation_id');\n  }\n}\n```\n\n### getUserSimulations()\n\nRetrieves all simulations for the authenticated user. Useful when the simulation ID is not stored locally.\n\n**Returns:** `Promise<Array<{ simulationId: string; phase: CreationPhase }>>`\n\n**Example:**\n\n```typescript\nconst simulations = await client.getUserSimulations();\nconst inProgress = simulations.find(\n  sim => sim.phase !== CreationPhase.FINISHED && sim.phase !== CreationPhase.ERROR\n);\n```\n\n<!--\n## Call Recovery\n\nThe SDK automatically handles call recovery in case of page refreshes or browser closures during active calls. This ensures that call data is never lost and all calls get properly processed by the backend, even if the page is refreshed while a call is in progress.\n\n### How It Works\n\nWhen you start a call, the SDK stores minimal call state in the browser's localStorage. If the page is refreshed:\n\n1. **On app initialization**: The `recoverAbandonedCall()` method checks for any stored call state\n2. **Age-based recovery**: Calls older than 5 minutes are considered abandoned and automatically recovered\n3. **Backend notification**: The backend is notified to process the call's transcript, recording, and analytics\n4. **Automatic cleanup**: The stored state is cleared after recovery or when a call ends naturally\n\nThis recovery mechanism works in **two stages** to ensure complete data integrity:\n\n- **Stage 1 (App Init)**: Recovers truly abandoned calls (>5 minutes old)\n- **Stage 2 (New Call Start)**: Notifies backend of ANY previous call before starting a new one\n\nThis dual approach ensures no call data is ever lost, regardless of user behavior patterns.\n\n### Integration\n\n#### Angular\n\nCall `recoverAbandonedCall()` during component initialization:\n\n```typescript\nimport { Component, OnInit } from '@angular/core';\nimport { PlatoApiClient } from 'plato-sdk';\n\n@Component({\n  selector: 'app-training',\n  templateUrl: './training.component.html',\n})\nexport class TrainingComponent implements OnInit {\n  constructor(private platoClient: PlatoApiClient) {}\n\n  async ngOnInit(): Promise<void> {\n    // Recover any abandoned calls from previous session\n    const recovered = await this.platoClient.recoverAbandonedCall();\n\n    if (recovered) {\n      console.log('Recovered abandoned call from previous session');\n      // Optional: Show notification to user\n      this.showNotification('Previous call data recovered and processed');\n    }\n\n    // Continue with normal initialization\n    await this.loadSimulations();\n  }\n\n  showNotification(message: string) {\n    // Your notification logic here\n  }\n}\n```\n\n#### React\n\nCall `recoverAbandonedCall()` in a useEffect hook:\n\n```typescript\nimport { useEffect, useState } from 'react';\nimport { PlatoApiClient } from 'plato-sdk';\n\nfunction TrainingApp() {\n  const [platoClient] = useState(() => new PlatoApiClient({\n    baseUrl: 'https://your-api.com',\n    jwtToken: 'your-jwt-token',\n    publicKey: 'your-public-key',\n  }));\n\n  useEffect(() => {\n    const recoverCall = async () => {\n      try {\n        const recovered = await platoClient.recoverAbandonedCall();\n\n        if (recovered) {\n          console.log('Recovered abandoned call');\n          // Optional: Show toast notification\n          showToast('Previous call data recovered');\n        }\n      } catch (error) {\n        console.error('Recovery error:', error);\n      }\n    };\n\n    recoverCall();\n  }, [platoClient]);\n\n  return (\n    // Your app UI\n  );\n}\n```\n\n### recoverAbandonedCall()\n\nRecovers and processes any abandoned calls from previous sessions.\n\n**Returns:** `Promise<boolean>`\n\n- `true` if an abandoned call was found and recovered\n- `false` if no abandoned call exists or the call is too recent (<5 minutes)\n\n**Example:**\n\n```typescript\n// Check if any calls were recovered\nconst wasRecovered = await client.recoverAbandonedCall();\n\nif (wasRecovered) {\n  // An abandoned call was processed\n  console.log('Successfully recovered abandoned call');\n} else {\n  // No recovery needed\n  console.log('No abandoned calls to recover');\n}\n```\n\n### Behavior Details\n\n#### When Recovery Happens\n\n**Scenario 1: Abandoned Call (>5 minutes)**\n\n```\n10:00:00 - User starts call → State stored\n10:02:00 - User closes browser\n10:08:00 - User returns and opens app\n10:08:01 - recoverAbandonedCall() detects call (>5 min old)\n10:08:01 - Backend notified → Call processed ✓\n```\n\n**Scenario 2: Recent Call (<5 minutes)**\n\n```\n10:00:00 - User starts call → State stored\n10:01:00 - User refreshes page\n10:01:01 - recoverAbandonedCall() checks call (1 min old)\n10:01:01 - Too recent, skip recovery\n10:03:00 - User starts new call\n10:03:00 - startCall() detects previous call\n10:03:00 - Backend notified of previous call → Processed ✓\n10:03:01 - New call starts\n```\n\n#### Automatic Cleanup\n\nThe SDK automatically clears stored call state when:\n\n1. **Call ends naturally**: When `call-end` event fires\n2. **User stops call**: When `stopCall()` is called manually\n3. **New call starts**: Before starting a new call (after notifying backend of previous call)\n4. **After recovery**: After successfully notifying backend of abandoned call\n\n### Technical Details\n\n#### What Gets Stored\n\nThe SDK stores minimal state in `localStorage` under the key `plato_active_call`:\n\n```typescript\n{\n  callId: \"mongodb-call-id\",           // MongoDB ID for backend notification\n  externalCallId: \"external-provider-id\", // External provider's call ID\n  simulationId: \"simulation-id\",        // Associated simulation\n  startedAt: \"2025-01-15T10:00:00Z\",   // ISO 8601 timestamp\n  version: 1                            // Schema version for future compatibility\n}\n```\n\n#### Privacy & Storage\n\n- **Storage location**: Browser localStorage (persists across sessions)\n- **Data size**: ~300 bytes (minimal footprint)\n- **Privacy**: Stored locally, never sent to third parties\n- **Graceful degradation**: If localStorage is disabled (e.g., private browsing), the SDK continues to work normally but recovery won't be available\n\n#### Backend Idempotency\n\nThe backend `/api/v1/postcall/call-ended` endpoint is idempotent, meaning:\n\n- ✅ Safe to call multiple times for the same call\n- ✅ No duplicate processing or data corruption\n- ✅ Recovery logic can safely notify backend even if uncertain\n\nThis design ensures **data integrity** over potential duplicate notifications.\n\n### Edge Cases\n\n#### Multiple Tabs\n\nIf you have multiple tabs open:\n\n- Only the most recent call state is stored (single localStorage key)\n- Each new call in any tab overwrites previous state\n- The most recent call is recovered if needed\n\n**Impact**: Minimal - calls typically happen one at a time, and the backend handles all notifications properly.\n\n#### Rapid Actions\n\nIf the user refreshes immediately after starting a call:\n\n- The call state is stored but not considered abandoned (<5 minutes)\n- When the user starts a new call later, the previous call is automatically notified to backend\n- No data loss occurs\n\n#### Browser Closure\n\nIf the browser is force-closed during a call:\n\n- State persists in localStorage\n- On next app launch, recovery detects and processes the call\n- Call data is recovered successfully\n\n#### localStorage Disabled\n\nIf localStorage is disabled (e.g., private browsing mode):\n\n- All storage operations fail silently\n- No errors thrown\n- SDK continues to work for normal call flow\n- Recovery simply won't be available\n\n**This is acceptable** because localStorage is enabled in 99%+ of browsers.\n\n### Best Practices\n\n1. **Always call `recoverAbandonedCall()`** during app initialization to ensure data integrity\n2. **Call it early** in your initialization flow, before other operations\n3. **Handle the return value** to show user notifications when calls are recovered\n4. **Don't block UI** - recovery is fast (<500ms typically) but async\n5. **Trust the system** - the SDK and backend handle all edge cases automatically\n\n### Example: Complete Integration\n\n```typescript\n// Angular Component\n@Component({\n  selector: 'app-root',\n  templateUrl: './app.component.html',\n})\nexport class AppComponent implements OnInit {\n  constructor(private platoClient: PlatoApiClient, private toastr: ToastrService) {}\n\n  async ngOnInit(): Promise<void> {\n    try {\n      // Step 1: Recover any abandoned calls\n      const recovered = await this.platoClient.recoverAbandonedCall();\n\n      if (recovered) {\n        this.toastr.info('Previous call data was recovered and processed');\n      }\n\n      // Step 2: Continue with normal app initialization\n      await this.loadUserData();\n      await this.loadSimulations();\n    } catch (error) {\n      console.error('Initialization error:', error);\n    }\n  }\n\n  async startCall(simulationId: string): Promise<void> {\n    try {\n      // The SDK automatically handles any previous call state\n      const call = await this.platoClient.startCall(simulationId);\n\n      call.on('call-end', () => {\n        console.log('Call ended');\n        // State automatically cleared\n      });\n\n      call.on('call-details-ready', callDetails => {\n        console.log('Feedback ready:', callDetails);\n      });\n    } catch (error) {\n      console.error('Call error:', error);\n    }\n  }\n}\n```\n\n### Troubleshooting\n\n**Q: What if I forget to call `recoverAbandonedCall()`?**\n\nA: The SDK still protects against data loss through Stage 2 recovery - when you start a new call, it automatically notifies the backend of any previous call. However, it's still recommended to call `recoverAbandonedCall()` for optimal behavior.\n\n**Q: Can I disable call recovery?**\n\nA: While you can skip calling `recoverAbandonedCall()`, the Stage 2 recovery (in `startCall()`) always runs to prevent data loss. This is by design to ensure data integrity.\n\n**Q: How do I know if a call was recovered?**\n\nA: The `recoverAbandonedCall()` method returns `true` when a call is recovered. Use this to show user notifications or update UI accordingly.\n\n**Q: What if the backend is down during recovery?**\n\nA: The recovery attempt is logged and the stored state is cleared to prevent infinite retries. The SDK continues working normally. Recovery failures are graceful and don't break the app.\n-->\n\n## Slide-Aware Conversations\n\nWhen a simulation is linked to a PDF (`pdfSlideId`), the user navigates through slides while talking to the assistant. `notifySlideChange` lets you push the current slide number to the assistant so it always has up-to-date context — without requiring the user to say \"I'm on slide 3\" out loud.\n\n### How It Works\n\nThe method sends a silent system message to the voice session. The assistant reads it as background context and never reads it aloud or reacts to it directly.\n\n```typescript\ncall.notifySlideChange(3); // tell the assistant the user is now on slide 3\n```\n\n### Recommended Pattern: Defer Until the User Speaks\n\nSending `notifySlideChange` the moment the user clicks \"Next\" works, but can cause the assistant to receive mid-conversation context updates while it is already responding. A better approach is to **hold the slide number in a pending state and flush it only when the user next starts talking**. This way the assistant always receives the update at a natural boundary, and multiple rapid navigations collapse into a single notification (the last pending slide wins).\n\n```typescript\nlet pendingSlideNumber: number | undefined;\n\nconst call = await client.startCall(simulationId);\n\n// Load and sort slides\nconst slideData = await client.getSlideAnalysis(pdfSlideId);\nconst slides = slideData.slideAnalysis?.sort((a, b) => a.slideNumber - b.slideNumber) ?? [];\nlet currentSlideIndex = 0;\n\n// Flush the pending slide the moment the user starts speaking\ncall.on('message', event => {\n  if (event.type === 'transcript' && event.role === 'user' && pendingSlideNumber !== undefined) {\n    call.notifySlideChange(pendingSlideNumber);\n    pendingSlideNumber = undefined;\n  }\n});\n\n// When the user navigates, store the slide number — don't send it yet\nfunction goToSlide(index: number): void {\n  currentSlideIndex = index;\n  pendingSlideNumber = slides[currentSlideIndex].slideNumber;\n}\n```\n\n## Event System\n\nThe SDK provides a comprehensive event system for managing voice calls:\n\n### Available Events\n\n- `call-start`: Triggered when a call begins\n- `call-end`: Triggered when a call ends\n- `speech-start`: Triggered when speech detection starts\n- `speech-end`: Triggered when speech detection ends\n- `message`: Triggered when a message is received (contains transcript and metadata)\n- `volume-level`: Triggered with volume level updates (number)\n- `error`: Triggered when an error occurs\n- `call-ended-reason`: Triggered just before `call-end` with the reason the call was terminated (e.g. silence timeout). Use this to show the user a contextual message immediately\n- `call-details-ready`: Triggered when post-call processing completes and call details are available (includes full `CallDTO` with transcript, summary, ratings, and evaluation)\n\n### Event Usage\n\n```typescript\n// Subscribe to events\ncall.on('message', message => {\n  console.log('Transcript:', message.transcript);\n  console.log('Type:', message.transcriptType); // 'final' or 'partial'\n});\n\ncall.on('volume-level', level => {\n  console.log('Volume level:', level);\n});\n\ncall.on('error', error => {\n  console.error('Call error:', error);\n});\n\n// Listen for call details after post-call processing\ncall.on('call-details-ready', callDetails => {\n  console.log('Post-call feedback ready:', callDetails);\n});\n```\n\n## Detecting Why a Call Ended\n\nThe `call-ended-reason` event fires **just before** `call-end`, giving you the reason the call was terminated in time to update the UI before any post-call processing begins.\n\n### Usage\n\n```typescript\ncall.on('call-ended-reason', ({ reason, isInactivity }) => {\n  // reason      — raw string from the platform, e.g. \"silence-timed-out\"\n  // isInactivity — true when reason contains \"silence\" or \"inactivity\"\n});\n```\n\n### Known Reason Values\n\n| `reason`              | `isInactivity` | When it occurs                                          |\n| --------------------- | -------------- | ------------------------------------------------------- |\n| `silence-timed-out`   | `true`         | No speech detected within the configured silence window |\n| `customer-ended-call` | `false`        | The user clicked \"End Call\"                             |\n| `pipeline-error`      | `false`        | An internal platform error terminated the call          |\n\n> **Note:** The `reason` field reflects the raw value from the underlying voice platform. New values may be introduced over time. Always handle unknown reasons gracefully by falling back to a generic message.\n\n## Automatic Post-Call Feedback\n\nThe SDK automatically fetches detailed call information after each call ends and completes post-call processing. This includes comprehensive feedback such as transcript, summary, evaluation metrics, strengths, weaknesses, and ratings.\n\n### How It Works\n\nWhen a call ends, the SDK automatically:\n\n1. Triggers the `call-end` event\n2. Processes the call on the backend (post-call analysis)\n3. Fetches complete call details\n4. Emits the `call-details-ready` event with full `CallDTO` data\n\nThis happens automatically—you don't need to manually call `getCallDetails()` after each call.\n\n### Event Lifecycle\n\n```typescript\nconst call = await client.startCall(simulationId);\n\n// 1. Call begins\ncall.on('call-start', () => {\n  console.log('Call started');\n});\n\n// 2. Real-time transcript messages during the call\ncall.on('message', message => {\n  console.log('Real-time:', message.transcript);\n});\n\n// 3. Call ends\ncall.on('call-end', () => {\n  console.log('Call ended - processing feedback...');\n});\n\n// 4. Post-call details are automatically fetched and ready\ncall.on('call-details-ready', callDetails => {\n  console.log('Post-call feedback is ready!');\n\n  // Access all call details\n  console.log('Summary:', callDetails.summary);\n  console.log('Full Transcript:', callDetails.transcript);\n  console.log('Call Duration:', callDetails.callDurationMs, 'ms');\n  console.log('Success:', callDetails.successEvaluation);\n  console.log('Score:', callDetails.score);\n\n  // Display evaluation metrics\n  console.log(`${callDetails.metric1}: ${callDetails.metric1Value}`);\n  console.log(`${callDetails.metric2}: ${callDetails.metric2Value}`);\n  console.log(`${callDetails.metric3}: ${callDetails.metric3Value}`);\n\n  // Show strengths and areas for improvement\n  callDetails.strengths?.forEach(strength => {\n    console.log('✓ Strength:', strength);\n  });\n\n  callDetails.weaknesses?.forEach(weakness => {\n    console.log('⚠ Area to improve:', weakness);\n  });\n\n  // Access recording\n  if (callDetails.recordingUrl) {\n    console.log('Recording:', callDetails.recordingUrl);\n  }\n});\n```\n\n### Practical Use Cases\n\n#### 1. Display Post-Call Feedback in UI\n\n```typescript\n// Angular/React example\nasync startCall() {\n  const call = await this.client.startCall(this.simulationId);\n\n  // Automatically update UI when feedback is ready\n  call.on('call-details-ready', callDetails => {\n    this.callSummary = callDetails.summary;\n    this.callScore = callDetails.score;\n    this.strengths = callDetails.strengths;\n    this.weaknesses = callDetails.weaknesses;\n    this.showFeedbackModal = true; // Display feedback to user\n  });\n}\n```\n\n#### 2. Track Performance Analytics\n\n```typescript\ncall.on('call-details-ready', callDetails => {\n  // Send analytics to tracking service\n  analytics.track('call_completed', {\n    callId: callDetails._id,\n    duration: callDetails.callDurationMs,\n    score: callDetails.score,\n    success: callDetails.successEvaluation,\n    metrics: {\n      [callDetails.metric1]: callDetails.metric1Value,\n      [callDetails.metric2]: callDetails.metric2Value,\n      [callDetails.metric3]: callDetails.metric3Value,\n    },\n  });\n});\n```\n\n#### 3. Store Call History\n\n```typescript\ncall.on('call-details-ready', async callDetails => {\n  // Save to local storage or database\n  const callHistory = JSON.parse(localStorage.getItem('call_history') || '[]');\n  callHistory.push({\n    id: callDetails._id,\n    date: callDetails.createdAt,\n    summary: callDetails.summary,\n    score: callDetails.score,\n  });\n  localStorage.setItem('call_history', JSON.stringify(callHistory));\n});\n```\n\n#### 4. Generate Learning Insights\n\n```typescript\ncall.on('call-details-ready', callDetails => {\n  // Aggregate insights across multiple calls\n  if (callDetails.successEvaluation) {\n    this.successfulCalls++;\n    this.successStrategies.push(...(callDetails.strengths || []));\n  } else {\n    this.areasToImprove.push(...(callDetails.weaknesses || []));\n  }\n\n  this.updateLearningDashboard();\n});\n```\n\n### Manual Fetching (Alternative Approach)\n\nWhile the SDK automatically fetches call details after each call, you can also manually retrieve them later using the call ID:\n\n```typescript\n// Get call details at any time\nconst callDetails = await client.getCallDetails(callId);\n```\n\nThis is useful when:\n\n- Viewing historical calls\n- Refreshing data after updates\n- Building a call history view\n\n### Error Handling\n\nIf fetching call details fails after a call ends, the error is logged but does not prevent the `call-end` event from completing. The call will still end gracefully.\n\n```typescript\ncall.on('call-end', () => {\n  console.log('Call ended successfully');\n  // This will always fire, even if call-details-ready fails\n});\n\ncall.on('call-details-ready', callDetails => {\n  // This may not fire if post-call processing fails\n  // In that case, you can manually fetch later using getCallDetails()\n});\n```\n\n### Best Practices\n\n1. **Always subscribe to `call-details-ready`** to capture post-call feedback automatically\n2. **Show loading state** between `call-end` and `call-details-ready` events\n3. **Handle missing data gracefully** - some fields may be `null` or `undefined` depending on call status\n4. **Store call IDs** for later retrieval using `getCallDetails()` if needed\n5. **Use the event data** to provide immediate feedback to users rather than making additional API calls\n\n### Timing Considerations\n\n- `call-ended-reason`: Fires immediately before `call-end`, with the reason the call stopped\n- `call-end`: Fires immediately when the call stops\n- `call-details-ready`: Fires after backend processing completes (typically 2-5 seconds after call ends)\n\nPlan your UX accordingly—show a contextual end message on `call-ended-reason`, then a loading/processing state until `call-details-ready` arrives.\n\n### Call Duration and Data Availability\n\nThe quality of data returned in `call-details-ready` depends on the duration of the call:\n\n| Call duration     | Behaviour                                                                                                                                                                                                                                                                   |\n| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **< ~15 seconds** | `call-details-ready` fires immediately after `call-end` with whatever the database currently holds. Fields like `transcript`, `summary`, `score`, `strengths`, and `weaknesses` will typically be empty or zero — the call was too short to generate a meaningful analysis. |\n| **≥ ~15 seconds** | The SDK polls the backend until Vapi's post-call analysis is ready (transcript present), then emits `call-details-ready` with the fully populated `CallDTO`.                                                                                                                |\n\n> **Note:** The ~15 second threshold accounts for the Vapi connection handshake (typically 1–5 seconds) plus a minimum amount of conversation time required for analysis to be generated. Always handle empty fields gracefully regardless of call length.\n\n## Data Types\n\n### CallDTO\n\nComplete call details returned by `call-details-ready` event and `getCallDetails()` method:\n\n```typescript\ninterface CallDTO {\n  _id: string; // MongoDB ID of the call\n  callId: string; // Vapi call ID\n  assistantId: string; // ID of the AI assistant used\n  summary?: string; // AI-generated summary of the conversation\n  transcript?: string; // Full transcript of the call\n  recordingUrl?: string; // URL to the call recording\n  rating?: number; // User-provided rating (0-5)\n  successEvaluation?: boolean; // Whether the call was successful\n  score?: number; // Overall score for the call\n  strengths?: string[]; // Array of identified strengths\n  weaknesses?: string[]; // Array of areas for improvement\n  metric1?: string; // Name of evaluation metric 1\n  metric1Value?: number; // Value for metric 1\n  metric2?: string; // Name of evaluation metric 2\n  metric2Value?: number; // Value for metric 2\n  metric3?: string; // Name of evaluation metric 3\n  metric3Value?: number; // Value for metric 3\n  createdAt: Date; // When the call was created\n  endedAt?: Date; // When the call ended\n  callDurationMs?: number; // Duration in milliseconds\n  // Additional fields may be present depending on call status\n}\n```\n\n### CreateSimulationDto\n\nConfiguration for creating a simulation:\n\n```typescript\ninterface CreateSimulationDto {\n  persona: CharacterCreateDto;\n  product: ProductConfig;\n  scenario: string;\n  objectives?: string;\n  anticipatedObjections?: string;\n  imageId: string;\n  avatarLanguage: AvatarLanguage;\n  pdfSlideId?: string;\n  isLearning?: boolean;\n}\n```\n\n### CharacterCreateDto\n\nAI persona configuration:\n\n```typescript\ninterface CharacterCreateDto {\n  name: string;\n  professionalProfile: ProfessionalProfileDto;\n  segment: SegmentType;\n  personalityAndBehaviour: PersonalityAndBehaviourDto;\n  context: ContextDto;\n  assistantGender?: AssistantVoiceGender;\n}\n```\n\n### SimulationDetailsDto\n\nDetailed simulation information returned by `getSimulationDetails()`:\n\n```typescript\ninterface SimulationDetailsDto {\n  simulationId: string;\n  phase: CreationPhase;\n  assistantId: string;\n  configuration?: CreateSimulationDto;\n  simulationBriefing?: SimulationBriefingDto;\n  createdAt: Date;\n  updatedAt: Date;\n}\n```\n\n### SimulationBriefingDto\n\nStructured briefing data generated by the multi-agent system. This data provides context about the simulation's objectives, persona, and scenario:\n\n```typescript\ninterface SimulationBriefingDto {\n  objectiveTag: string;\n  personaDescription: PersonaDescriptionDto;\n  scenarioContext: ScenarioContextDto;\n  trainingObjective: TrainingObjectiveDto;\n}\n\ninterface PersonaDescriptionDto {\n  summary: string;\n  details: string[];\n}\n\ninterface ScenarioContextDto {\n  summary: string;\n  steps: string[];\n}\n\ninterface TrainingObjectiveDto {\n  summary: string;\n  keyObjectives: string[];\n}\n```\n\n**Example:**\n\n```typescript\nconst details = await client.getSimulationDetails(simulationId);\n\nif (details.simulationBriefing) {\n  console.log('Objective:', details.simulationBriefing.objectiveTag);\n  console.log('Persona:', details.simulationBriefing.personaDescription.summary);\n  console.log('Scenario:', details.simulationBriefing.scenarioContext.summary);\n  console.log('Training Goals:', details.simulationBriefing.trainingObjective.keyObjectives);\n}\n```\n\n**Note:** The `simulationBriefing` field is optional and will only be present for simulations created after the briefing feature was implemented.\n\n### CreationPhase\n\nEnum representing the simulation creation phases:\n\n```typescript\nenum CreationPhase {\n  STARTING = 'STARTING',\n  BUILD_HEADER = 'BUILD_HEADER',\n  SEGMENT_SELECTED = 'SEGMENT_SELECTED',\n  BUILD_CONTEXT = 'BUILD_CONTEXT',\n  BUILD_PSYCHOGRAPHICS = 'BUILD_PSYCHOGRAPHICS',\n  BUILD_OBJECTIVES = 'BUILD_OBJECTIVES',\n  PERSONA_ASSEMBLED = 'PERSONA_ASSEMBLED',\n  CORE = 'CORE',\n  BOUNDARIES = 'BOUNDARIES',\n  SPEECH_AND_THOUGHT = 'SPEECH_AND_THOUGHT',\n  CONVERSATION_EVOLUTION = 'CONVERSATION_EVOLUTION',\n  MEMORY = 'MEMORY',\n  OBJECTION_HANDLING = 'OBJECTION_HANDLING',\n  PERFORMANCE_EVALUATION = 'PERFORMANCE_EVALUATION',\n  BEHAVIORAL_FRAMEWORKS = 'BEHAVIORAL_FRAMEWORKS',\n  FINISHED = 'FINISHED',\n  ERROR = 'ERROR',\n}\n```\n\n### RecommendationsResponseDto\n\nResponse object from `getRecommendations()`:\n\n```typescript\ninterface RecommendationsResponseDto {\n  recommendations: RecommendationItemDto[];\n  strengths: PerformancePatternDto[];\n  improvementAreas: ImprovementAreaDto[];\n  summary: string;\n  callsAnalyzed: number;\n  generatedAt: Date;\n}\n\ninterface RecommendationItemDto {\n  title: string;\n  description: string;\n  priority: 'high' | 'medium' | 'low';\n}\n\ninterface PerformancePatternDto {\n  strength: string;\n  frequency: number;\n}\n\ninterface ImprovementAreaDto {\n  area: string;\n  frequency: number;\n}\n```\n\n### PdfSlidesDto\n\nSimplified data structure for PDF slide records (used in lists):\n\n```typescript\ninterface PdfSlidesDto {\n  _id: string;\n  status: PdfSlidesStatus;\n  originalFilename: string;\n  totalSlides?: number;\n  lessonOverview?: string;\n  createdAt: Date;\n  updatedAt: Date;\n}\n```\n\n### PdfSlideDto\n\nDetailed data structure for a single PDF slide analysis:\n\n```typescript\ninterface PdfSlideDto {\n  _id: string;\n  status: PdfSlidesStatus;\n  originalFilename: string;\n  totalSlides?: number;\n  lessonOverview?: string;\n  slideAnalysis?: Array<{\n    slideNumber: number;\n    title: string;\n    textExtraction: string;\n  }>;\n  createdAt: Date;\n  updatedAt: Date;\n}\n```\n\n### PdfSlidesStatus\n\nEnum representing the PDF analysis workflow status:\n\n```typescript\nenum PdfSlidesStatus {\n  STARTED = 'started',\n  PROCESSING = 'processing',\n  OVERVIEW = 'overview',\n  COMPLETED = 'completed',\n  FAILED = 'failed',\n}\n```\n\n### PdfSlidesAnalysisQueryDto\n\nQuery parameters for retrieving slide analysis records:\n\n```typescript\ninterface PdfSlidesAnalysisQueryDto {\n  limit?: 5 | 10 | 25;\n  page?: number;\n  sort?: 'asc' | 'desc';\n  sortBy?: 'createdAt' | 'originalFilename' | 'totalSlides';\n}\n```\n\n### AssistantImageDto\n\nData structure for assistant images:\n\n```typescript\ninterface AssistantImageDto {\n  _id: string;\n  imageUrl: string;\n}\n```\n\n### SegmentType\n\nEnum representing available doctor persona segments:\n\n```typescript\nenum SegmentType {\n  Traditionalist = 'The Traditionalist',\n  Innovator = 'The Innovator',\n  PatientOrientedPhysician = 'The Patient-Oriented Physician',\n  FinanciallyDrivenPrescriber = 'The Financially-Driven Prescriber',\n  EvidencePurist = 'The Evidence-Purist',\n  CostConsciousPrescriber = 'The Cost-Conscious Prescriber',\n}\n```\n\n### AvatarLanguage\n\nEnum representing available avatar languages:\n\n```typescript\nenum AvatarLanguage {\n  English = 'en',\n  German = 'de',\n  Spanish = 'es',\n  Italian = 'it',\n  French = 'fr',\n  Arabic = 'ar',\n  Russian = 'ru',\n}\n```\n\n## Error Handling\n\nThe SDK throws errors for invalid configurations and API failures:\n\n```typescript\ntry {\n  const client = new PlatoApiClient({\n    baseUrl: 'https://api.plato.com',\n    jwtToken: 'your-jwt-token',\n    publicKey: 'your-public-key',\n  });\n\n  const simulation = await client.createSimulation(simulationConfig);\n  const call = await client.startCall(simulation.simulationId);\n} catch (error) {\n  console.error('Error:', error.message);\n}\n```\n\n### PDF Already Exists Error\n\nWhen a PDF with identical content has already been uploaded by your organization, `uploadPdfSlides()` throws a `PdfAlreadyExistsError`. The error exposes the `pdfId` of the existing record so you can use it directly without re-uploading.\n\n```typescript\nimport { PdfAlreadyExistsError } from 'plato-sdk';\n\ntry {\n  const pdfId = await client.uploadPdfSlides(file);\n} catch (error) {\n  if (error instanceof PdfAlreadyExistsError) {\n    console.log('PDF already exists, using existing ID:', error.pdfId);\n  } else {\n    console.error('Upload failed:', error.message);\n  }\n}\n```\n\n### Concurrency Limit Error\n\nWhen the platform has reached its maximum number of simultaneous active calls, `startCall()` throws a `CallConcurrencyLimitError`. This is a platform-wide limit, not user-specific. You should catch this specifically and show the user a clear message rather than a generic error.\n\n```typescript\nimport { CallConcurrencyLimitError } from 'plato-sdk';\n\nconst handleStartCall = async (simulationId: string) => {\n  try {\n    const call = await platoClient.startCall(simulationId);\n\n    call.on('call-start', () => setCallActive(true));\n    call.on('call-end', () => setCallActive(false));\n  } catch (error) {\n    if (error instanceof CallConcurrencyLimitError) {\n      setErrorMessage(\n        'The platform has reached its maximum number of simultaneous calls. Please try again in a moment.'\n      );\n    } else {\n      setErrorMessage('Failed to start call. Please try again.');\n    }\n  }\n};\n```\n\n## Support\n\nFor support and questions, please contact the development team.\n","readmeFilename":"README.md"}