From bb892898c95a70c7ffc25805ab37fdb78dfccc72 Mon Sep 17 00:00:00 2001 From: mkm17 Date: Mon, 30 Sep 2024 21:52:55 +0200 Subject: [PATCH] Adds `spp model get` command closes #6105 --- docs/docs/cmd/spp/model/model-get.mdx | 994 ++++++++++++++++++ docs/src/config/sidebars.ts | 5 + src/m365/spp/commands.ts | 1 + src/m365/spp/commands/model/model-get.spec.ts | 379 +++++++ src/m365/spp/commands/model/model-get.ts | 146 +++ src/utils/spp.ts | 4 + 6 files changed, 1529 insertions(+) create mode 100644 docs/docs/cmd/spp/model/model-get.mdx create mode 100644 src/m365/spp/commands/model/model-get.spec.ts create mode 100644 src/m365/spp/commands/model/model-get.ts diff --git a/docs/docs/cmd/spp/model/model-get.mdx b/docs/docs/cmd/spp/model/model-get.mdx new file mode 100644 index 00000000000..d42ed5b5ca1 --- /dev/null +++ b/docs/docs/cmd/spp/model/model-get.mdx @@ -0,0 +1,994 @@ +import Global from '/docs/cmd/_global.mdx'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# spp model get + +Retrieves information about a document understanding model + +## Usage + +```sh +m365 spp model get [options] +``` + +## Options + +```md definition-list +`-u, --siteUrl ` +: The URL of the content center site. + +`-i, --id [id]` +: The unique ID of the model to retrieve. Specify `id` or `title` but not both. + +`-t, --title [title]` +: The display name of the model to retrieve. Specify `id` or `title` but not both. + +`--withPublications` +: Retrieves information about the library where it has been applied. +``` + + + +## Examples + +Retrieve information about a SharePoint Premium document understanding model, using model UniqueId. + +```sh +m365 spp model get --siteUrl "https://contoso.sharepoint.com/sites/ContentCenter" --id "7645e69d-21fb-4a24-a17a-9bdfa7cb63dc" +``` + +Retrieve information about a SharePoint Premium document understanding model, using model Title + +```sh +m365 spp model get --siteUrl "https://contoso.sharepoint.com/sites/ContentCenter" --title "climicrosoft365Model" +``` + +## Response + +### Standard response + + + + + ```json + { + "AIBuilderHybridModelType": null, + "AzureCognitivePrebuiltModelName": null, + "BaseContentTypeName": null, + "ConfidenceScore": { + "trainingStatus": { + "kind": "original", + "ClassifierStatus": { + "TrainingStatus": "success", + "TimeStamp": 1604429035541 + }, + "ExtractorsStatus": [ + { + "TimeStamp": 1595871764667, + "ExtractorName": "Adressee", + "TrainingStatus": "success" + }, + { + "TimeStamp": 1595871896822, + "ExtractorName": "Discount Percentage", + "TrainingStatus": "success" + }, + { + "TimeStamp": 1595871961934, + "ExtractorName": "Date of Change", + "TrainingStatus": "success" + }, + { + "TimeStamp": 1604407772191, + "ExtractorName": "Date Completed", + "TrainingStatus": "success" + }, + { + "TimeStamp": 1604429033385, + "ExtractorName": "Contributor", + "TrainingStatus": "success" + } + ] + }, + "modelAccuracy": { + "Classifier": 1, + "Extractors": { + "Adressee": 1, + "Discount Percentage": 1, + "Date of Change": 1, + "Date Completed": 1, + "Contributor": 1 + } + }, + "perSampleAccuracy": { + "43": { + "Classifier": 1, + "Extractors": { + "Contributor": 1 + } + }, + "44": { + "Classifier": 1, + "Extractors": { + "Contributor": 1 + } + }, + "45": { + "Classifier": 1, + "Extractors": { + "Contributor": 1 + } + }, + "48": { + "Classifier": 1, + "Extractors": { + "Contributor": 1 + } + }, + "50": { + "Classifier": 1, + "Extractors": { + "Contributor": 1 + } + }, + "52": { + "Classifier": 1, + "Extractors": {} + } + }, + "perSamplePrediction": { + "43": { + "Extractors": { + "Contributor": [ + "Benefit Change Notice" + ] + } + }, + "44": { + "Extractors": { + "Contributor": [ + "Benefit Change Notice" + ] + } + }, + "45": { + "Extractors": { + "Contributor": [ + "Benefit Change Notice" + ] + } + }, + "48": { + "Extractors": { + "Contributor": [ + "Benefit Change Notice" + ] + } + }, + "50": { + "Extractors": { + "Contributor": [ + "Benefit Change Notice" + ] + } + } + }, + "trainingFailures": {} + }, + "ContentTypeGroup": "Intelligent Document Content Types", + "ContentTypeId": "0x010100B992472522B7C04E9101F1CFD07E4ADC", + "ContentTypeName": "BenefitsChangeNotice", + "Created": "2020-11-03T12:30:55Z", + "CreatedBy": "i:0#.w|sharepoint\\system", + "DriveId": "b!7w273MPU8kiqSKc6SWaUkQ3wyRgeHbxDh-e6ShP9X-cXa2m8jDdHQ7UJXVLMbzgj", + "Explanations": { + "Classifier": [ + { + "id": "24f0b71f-87c6-4f7d-9797-88e9eab00cb6", + "kind": "dictionaryFeature", + "name": "Contains ", + "active": true, + "nGrams": [ + "Benefit Change Notice" + ], + "caseSensitive": true, + "ignoreDigitIdentity": false, + "ignoreLetterIdentity": false + }, + { + "id": "849c3ca4-296a-4209-be33-d5be0f942d39", + "kind": "modelFeature", + "name": "Adressee", + "active": true, + "modelReference": "Adressee", + "conceptId": "0a18ef8b-c0cd-435d-8a45-37738fef4f6f" + }, + { + "id": "41f80170-c054-42ae-8b30-cd0d9bc35874", + "kind": "modelFeature", + "name": "Discount Percentage", + "active": true, + "modelReference": "Discount Percentage", + "conceptId": "48c09840-d2da-4416-a02d-68113da24d18" + }, + { + "id": "c3c46580-5570-4ea7-baa9-69bfc1f9e088", + "kind": "modelFeature", + "name": "Date of Change", + "active": true, + "modelReference": "Date of Change", + "conceptId": "f39b4e2a-e945-4a2e-99a0-561334037a66" + }, + { + "id": "e138c9e0-849b-4207-9d5e-3e9925340bb5", + "kind": "modelFeature", + "name": "Date Completed", + "active": true, + "modelReference": "Date Completed", + "conceptId": "3559972a-d7c5-4ccb-b8cb-e4b852da2399" + }, + { + "id": "ceb16569-72a4-486a-a7cc-296bad0747c0", + "kind": "modelFeature", + "name": "Contributor", + "active": true, + "modelReference": "Contributor", + "conceptId": "6af8ef33-4bf1-49ca-93d3-7a2358746747" + } + ], + "Extractors": { + "Adressee": [ + { + "id": "c661eef3-c1cc-4c9f-a4c8-5b617dd46f88", + "kind": "dictionaryFeature", + "name": "", + "active": true, + "nGrams": [ + "Dear" + ], + "caseSensitive": true, + "ignoreDigitIdentity": false, + "ignoreLetterIdentity": false + } + ], + "Discount Percentage": [ + { + "id": "a4f9c304-8867-4b82-abb6-b968e7ebca3b", + "kind": "dictionaryFeature", + "name": "", + "active": true, + "nGrams": [ + "a" + ], + "caseSensitive": false, + "ignoreDigitIdentity": false, + "ignoreLetterIdentity": false + }, + { + "id": "73f7ba0b-e69e-418e-8483-201bb2fb9c54", + "kind": "dictionaryFeature", + "name": "", + "active": true, + "nGrams": [ + "%" + ], + "caseSensitive": false, + "ignoreDigitIdentity": false, + "ignoreLetterIdentity": false + }, + { + "id": "3e4f9a86-226d-4f4b-af7d-891dc817ee8d", + "kind": "proximityFeature", + "name": "Proximity Between ", + "active": true, + "patterns": [ + [ + { + "id": "a4f9c304-8867-4b82-abb6-b968e7ebca3b", + "kind": "proximityFeatureReference" + }, + { + "kind": "proximityTokenRange", + "minCount": 1, + "maxCount": 6 + }, + { + "id": "73f7ba0b-e69e-418e-8483-201bb2fb9c54", + "kind": "proximityFeatureReference" + } + ] + ] + } + ], + "Date of Change": [ + { + "id": "76ba0449-f94c-4b8c-bd9e-abbb89c6ae25", + "kind": "dictionaryFeature", + "name": "Date (numeric)", + "active": true, + "nGrams": [ + "1/1/11", + "1/11/11", + "11/1/11", + "11/11/11", + "1/1/1111", + "1/11/1111", + "11/1/1111", + "11/11/1111", + "1111/1/1", + "1111/1/11", + "1111/11/11", + "1111/11/11" + ], + "caseSensitive": true, + "ignoreDigitIdentity": true, + "ignoreLetterIdentity": false + } + ], + "Date Completed": [ + { + "id": "3f8b332a-abcd-4475-ad80-fbd827e265d4", + "kind": "dictionaryFeature", + "name": "Date (numeric)", + "active": true, + "nGrams": [ + "1/1/11", + "1/11/11", + "11/1/11", + "11/11/11", + "1/1/1111", + "1/11/1111", + "11/1/1111", + "11/11/1111", + "1111/1/1", + "1111/1/11", + "1111/11/11", + "1111/11/11" + ], + "caseSensitive": true, + "ignoreDigitIdentity": true, + "ignoreLetterIdentity": false + } + ], + "Contributor": [ + { + "id": "9abdbfc9-6425-4e03-a344-305d3e60ad7f", + "kind": "dictionaryFeature", + "name": "text", + "active": true, + "nGrams": [ + "Benefit Change Notice" + ], + "caseSensitive": false, + "ignoreDigitIdentity": false, + "ignoreLetterIdentity": false + } + ] + } + }, + "ID": 3, + "LastTrained": "2020-11-03T18:43:53Z", + "ListID": "bc696b17-378c-4347-b509-5d52cc6f3823", + "ModelSettings": null, + "ModelType": 2, + "Modified": "2024-06-27T02:45:32Z", + "ModifiedBy": "i:0#.w|sharepoint\\system", + "ObjectId": "01XHOXSCXFBUHLC2OA7FDJB52PXCWAAE3S", + "PublicationType": 0, + "Schemas": { + "Extractors": { + "Adressee": { + "concepts": { + "0a18ef8b-c0cd-435d-8a45-37738fef4f6f": { + "name": "Adressee" + } + }, + "relationships": [] + }, + "Discount Percentage": { + "concepts": { + "48c09840-d2da-4416-a02d-68113da24d18": { + "name": "Discount Percentage" + } + }, + "relationships": [] + }, + "Date of Change": { + "concepts": { + "f39b4e2a-e945-4a2e-99a0-561334037a66": { + "name": "Date of Change" + } + }, + "relationships": [] + }, + "Date Completed": { + "concepts": { + "3559972a-d7c5-4ccb-b8cb-e4b852da2399": { + "name": "Date Completed" + } + }, + "relationships": [] + }, + "Contributor": { + "concepts": { + "6af8ef33-4bf1-49ca-93d3-7a2358746747": { + "name": "Contributor" + } + }, + "relationships": [] + } + } + }, + "SourceSiteUrl": "https://contoso.sharepoint.com/sites/ContentCenter", + "SourceUrl": null, + "SourceWebServerRelativeUrl": "/sites/ContentCenter", + "UniqueId": "b10e0de5-c069-46f9-90f7-4fb8ac001372" + } + ``` + + + + + ```text + AIBuilderHybridModelType : null + AzureCognitivePrebuiltModelName: null + BaseContentTypeName : null + ConfidenceScore : {"trainingStatus":{"kind":"original","ClassifierStatus":{"TrainingStatus":"success","TimeStamp":1604429035541},"ExtractorsStatus":[{"TimeStamp":1595871764667,"ExtractorName":"Adressee","TrainingStatus":"success"},{"TimeStamp":1595871896822,"ExtractorName":"Discount Percentage","TrainingStatus":"success"},{"TimeStamp":1595871961934,"ExtractorName":"Date of Change","TrainingStatus":"success"},{"TimeStamp":1604407772191,"ExtractorName":"Date Completed","TrainingStatus":"success"},{"TimeStamp":1604429033385,"ExtractorName":"Contributor","TrainingStatus":"success"}]},"modelAccuracy":{"Classifier":1,"Extractors":{"Adressee":1,"Discount Percentage":1,"Date of Change":1,"Date Completed":1,"Contributor":1}},"perSampleAccuracy":{"43":{"Classifier":1,"Extractors":{"Contributor":1}},"44":{"Classifier":1,"Extractors":{"Contributor":1}},"45":{"Classifier":1,"Extractors":{"Contributor":1}},"48":{"Classifier":1,"Extractors":{"Contributor":1}},"50":{"Classifier":1,"Extractors":{"Contributor":1}},"52":{"Classifier":1,"Extractors":{}}},"perSamplePrediction":{"43":{"Extractors":{"Contributor":["Benefit Change Notice"]}},"44":{"Extractors":{"Contributor":["Benefit Change Notice"]}},"45":{"Extractors":{"Contributor":["Benefit Change Notice"]}},"48":{"Extractors":{"Contributor":["Benefit Change Notice"]}},"50":{"Extractors":{"Contributor":["Benefit Change Notice"]}}},"trainingFailures":{}} + ContentTypeGroup : Intelligent Document Content Types + ContentTypeId : 0x010100B992472522B7C04E9101F1CFD07E4ADC + ContentTypeName : BenefitsChangeNotice + Created : 2020-11-03T12:30:55Z + CreatedBy : i:0#.w|sharepoint\system + DriveId : b!7w273MPU8kiqSKc6SWaUkQ3wyRgeHbxDh-e6ShP9X-cXa2m8jDdHQ7UJXVLMbzgj + Explanations : {"Classifier":[{"id":"24f0b71f-87c6-4f7d-9797-88e9eab00cb6","kind":"dictionaryFeature","name":"Contains \"Benefit Change Notice\"","active":true,"nGrams":["Benefit Change Notice"],"caseSensitive":true,"ignoreDigitIdentity":false,"ignoreLetterIdentity":false},{"id":"849c3ca4-296a-4209-be33-d5be0f942d39","kind":"modelFeature","name":"Adressee","active":true,"modelReference":"Adressee","conceptId":"0a18ef8b-c0cd-435d-8a45-37738fef4f6f"},{"id":"41f80170-c054-42ae-8b30-cd0d9bc35874","kind":"modelFeature","name":"Discount Percentage","active":true,"modelReference":"Discount Percentage","conceptId":"48c09840-d2da-4416-a02d-68113da24d18"},{"id":"c3c46580-5570-4ea7-baa9-69bfc1f9e088","kind":"modelFeature","name":"Date of Change","active":true,"modelReference":"Date of Change","conceptId":"f39b4e2a-e945-4a2e-99a0-561334037a66"},{"id":"e138c9e0-849b-4207-9d5e-3e9925340bb5","kind":"modelFeature","name":"Date Completed","active":true,"modelReference":"Date Completed","conceptId":"3559972a-d7c5-4ccb-b8cb-e4b852da2399"},{"id":"ceb16569-72a4-486a-a7cc-296bad0747c0","kind":"modelFeature","name":"Contributor","active":true,"modelReference":"Contributor","conceptId":"6af8ef33-4bf1-49ca-93d3-7a2358746747"}],"Extractors":{"Adressee":[{"id":"c661eef3-c1cc-4c9f-a4c8-5b617dd46f88","kind":"dictionaryFeature","name":"\"Dear\"","active":true,"nGrams":["Dear"],"caseSensitive":true,"ignoreDigitIdentity":false,"ignoreLetterIdentity":false}],"Discount Percentage":[{"id":"a4f9c304-8867-4b82-abb6-b968e7ebca3b","kind":"dictionaryFeature","name":"\"a\"","active":true,"nGrams":["a"],"caseSensitive":false,"ignoreDigitIdentity":false,"ignoreLetterIdentity":false},{"id":"73f7ba0b-e69e-418e-8483-201bb2fb9c54","kind":"dictionaryFeature","name":"\"%\"","active":true,"nGrams":["%"],"caseSensitive":false,"ignoreDigitIdentity":false,"ignoreLetterIdentity":false},{"id":"3e4f9a86-226d-4f4b-af7d-891dc817ee8d","kind":"proximityFeature","name":"Proximity Between \"a\" and \"%\"","active":true,"patterns":[[{"id":"a4f9c304-8867-4b82-abb6-b968e7ebca3b","kind":"proximityFeatureReference"},{"kind":"proximityTokenRange","minCount":1,"maxCount":6},{"id":"73f7ba0b-e69e-418e-8483-201bb2fb9c54","kind":"proximityFeatureReference"}]]}],"Date of Change":[{"id":"76ba0449-f94c-4b8c-bd9e-abbb89c6ae25","kind":"dictionaryFeature","name":"Date (numeric)","active":true,"nGrams":["1/1/11","1/11/11","11/1/11","11/11/11","1/1/1111","1/11/1111","11/1/1111","11/11/1111","1111/1/1","1111/1/11","1111/11/11","1111/11/11"],"caseSensitive":true,"ignoreDigitIdentity":true,"ignoreLetterIdentity":false}],"Date Completed":[{"id":"3f8b332a-abcd-4475-ad80-fbd827e265d4","kind":"dictionaryFeature","name":"Date (numeric)","active":true,"nGrams":["1/1/11","1/11/11","11/1/11","11/11/11","1/1/1111","1/11/1111","11/1/1111","11/11/1111","1111/1/1","1111/1/11","1111/11/11","1111/11/11"],"caseSensitive":true,"ignoreDigitIdentity":true,"ignoreLetterIdentity":false}],"Contributor":[{"id":"9abdbfc9-6425-4e03-a344-305d3e60ad7f","kind":"dictionaryFeature","name":"text","active":true,"nGrams":["Benefit Change Notice"],"caseSensitive":false,"ignoreDigitIdentity":false,"ignoreLetterIdentity":false}]}} + ID : 3 + LastTrained : 2020-11-03T18:43:53Z + ListID : bc696b17-378c-4347-b509-5d52cc6f3823 + ModelSettings : null + ModelType : 2 + Modified : 2024-06-27T02:45:32Z + ModifiedBy : i:0#.w|sharepoint\system + ObjectId : 01XHOXSCXFBUHLC2OA7FDJB52PXCWAAE3S + PublicationType : 0 + SourceSiteUrl : https://contoso.sharepoint.com/sites/ContentCenter + SourceUrl : null + SourceWebServerRelativeUrl : /sites/ContentCenter + UniqueId : b10e0de5-c069-46f9-90f7-4fb8ac001372 + ``` + + + + + ```csv + AIBuilderHybridModelType,AzureCognitivePrebuiltModelName,BaseContentTypeName,ContentTypeGroup,ContentTypeId,ContentTypeName,Created,CreatedBy,DriveId,ID,LastTrained,ListID,ModelName,ModelType,Modified,ModifiedBy,ObjectId,PublicationType,SourceSiteUrl,SourceUrl,SourceWebServerRelativeUrl,UniqueId + ,,,Intelligent Document Content Types,0x010100B992472522B7C04E9101F1CFD07E4ADC,BenefitsChangeNotice,2020-11-03T12:30:55Z,i:0#.w|sharepoint\system,b!7w273MPU8kiqSKc6SWaUkQ3wyRgeHbxDh-e6ShP9X-cXa2m8jDdHQ7UJXVLMbzgj,3,2020-11-03T18:43:53Z,bc696b17-378c-4347-b509-5d52cc6f3823,B + ``` + + + + + ```md + # spp model get --siteUrl "https://contoso.sharepoint.com/sites/ContentCenter" --id "b10e0de5-c069-46f9-90f7-4fb8ac001372" + + Date: 29/09/2024 + + ## 3 + + Property | Value + ---------|------- + ContentTypeGroup | Intelligent Document Content Types + ContentTypeId | 0x010100B992472522B7C04E9101F1CFD07E4ADC + ContentTypeName | BenefitsChangeNotice + Created | 2020-11-03T12:30:55Z + CreatedBy | i:0#.w\|sharepoint\system + DriveId | b!7w273MPU8kiqSKc6SWaUkQ3wyRgeHbxDh-e6ShP9X-cXa2m8jDdHQ7UJXVLMbzgj + ID | 3 + LastTrained | 2020-11-03T18:43:53Z + ListID | bc696b17-378c-4347-b509-5d52cc6f3823 + ModelName | BenefitsChangeNotice + ModelType | 2 + Modified | 2024-11-08T04:49:57Z + ModifiedBy | i:0#.w\|sharepoint\system + ObjectId | 01XHOXSCXFBUHLC2OA7FDJB52PXCWAAE3S + PublicationType | 0 + SourceSiteUrl | https://contoso.sharepoint.com/sites/ContentCenter + SourceWebServerRelativeUrl | /sites/ContentCenter + UniqueId | b10e0de5-c069-46f9-90f7-4fb8ac001372 + ``` + + + + +### `withPublications` response + +When we make use of the option `withPublications`, the response will differ. + + + + + ```json + { + "AIBuilderHybridModelType": null, + "AzureCognitivePrebuiltModelName": null, + "BaseContentTypeName": null, + "ConfidenceScore": { + "trainingStatus": { + "kind": "original", + "ClassifierStatus": { + "TrainingStatus": "success", + "TimeStamp": 1604429035541 + }, + "ExtractorsStatus": [ + { + "TimeStamp": 1595871764667, + "ExtractorName": "Adressee", + "TrainingStatus": "success" + }, + { + "TimeStamp": 1595871896822, + "ExtractorName": "Discount Percentage", + "TrainingStatus": "success" + }, + { + "TimeStamp": 1595871961934, + "ExtractorName": "Date of Change", + "TrainingStatus": "success" + }, + { + "TimeStamp": 1604407772191, + "ExtractorName": "Date Completed", + "TrainingStatus": "success" + }, + { + "TimeStamp": 1604429033385, + "ExtractorName": "Contributor", + "TrainingStatus": "success" + } + ] + }, + "modelAccuracy": { + "Classifier": 1, + "Extractors": { + "Adressee": 1, + "Discount Percentage": 1, + "Date of Change": 1, + "Date Completed": 1, + "Contributor": 1 + } + }, + "perSampleAccuracy": { + "43": { + "Classifier": 1, + "Extractors": { + "Contributor": 1 + } + }, + "44": { + "Classifier": 1, + "Extractors": { + "Contributor": 1 + } + }, + "45": { + "Classifier": 1, + "Extractors": { + "Contributor": 1 + } + }, + "48": { + "Classifier": 1, + "Extractors": { + "Contributor": 1 + } + }, + "50": { + "Classifier": 1, + "Extractors": { + "Contributor": 1 + } + }, + "52": { + "Classifier": 1, + "Extractors": {} + } + }, + "perSamplePrediction": { + "43": { + "Extractors": { + "Contributor": [ + "Benefit Change Notice" + ] + } + }, + "44": { + "Extractors": { + "Contributor": [ + "Benefit Change Notice" + ] + } + }, + "45": { + "Extractors": { + "Contributor": [ + "Benefit Change Notice" + ] + } + }, + "48": { + "Extractors": { + "Contributor": [ + "Benefit Change Notice" + ] + } + }, + "50": { + "Extractors": { + "Contributor": [ + "Benefit Change Notice" + ] + } + } + }, + "trainingFailures": {} + }, + "ContentTypeGroup": "Intelligent Document Content Types", + "ContentTypeId": "0x010100B992472522B7C04E9101F1CFD07E4ADC", + "ContentTypeName": "BenefitsChangeNotice", + "Created": "2020-11-03T12:30:55Z", + "CreatedBy": "i:0#.w|sharepoint\\system", + "DriveId": "b!7w273MPU8kiqSKc6SWaUkQ3wyRgeHbxDh-e6ShP9X-cXa2m8jDdHQ7UJXVLMbzgj", + "Explanations": { + "Classifier": [ + { + "id": "24f0b71f-87c6-4f7d-9797-88e9eab00cb6", + "kind": "dictionaryFeature", + "name": "Contains Benefit Change Notice", + "active": true, + "nGrams": [ + "Benefit Change Notice" + ], + "caseSensitive": true, + "ignoreDigitIdentity": false, + "ignoreLetterIdentity": false + }, + { + "id": "849c3ca4-296a-4209-be33-d5be0f942d39", + "kind": "modelFeature", + "name": "Adressee", + "active": true, + "modelReference": "Adressee", + "conceptId": "0a18ef8b-c0cd-435d-8a45-37738fef4f6f" + }, + { + "id": "41f80170-c054-42ae-8b30-cd0d9bc35874", + "kind": "modelFeature", + "name": "Discount Percentage", + "active": true, + "modelReference": "Discount Percentage", + "conceptId": "48c09840-d2da-4416-a02d-68113da24d18" + }, + { + "id": "c3c46580-5570-4ea7-baa9-69bfc1f9e088", + "kind": "modelFeature", + "name": "Date of Change", + "active": true, + "modelReference": "Date of Change", + "conceptId": "f39b4e2a-e945-4a2e-99a0-561334037a66" + }, + { + "id": "e138c9e0-849b-4207-9d5e-3e9925340bb5", + "kind": "modelFeature", + "name": "Date Completed", + "active": true, + "modelReference": "Date Completed", + "conceptId": "3559972a-d7c5-4ccb-b8cb-e4b852da2399" + }, + { + "id": "ceb16569-72a4-486a-a7cc-296bad0747c0", + "kind": "modelFeature", + "name": "Contributor", + "active": true, + "modelReference": "Contributor", + "conceptId": "6af8ef33-4bf1-49ca-93d3-7a2358746747" + } + ], + "Extractors": { + "Adressee": [ + { + "id": "c661eef3-c1cc-4c9f-a4c8-5b617dd46f88", + "kind": "dictionaryFeature", + "name": "Dear", + "active": true, + "nGrams": [ + "Dear" + ], + "caseSensitive": true, + "ignoreDigitIdentity": false, + "ignoreLetterIdentity": false + } + ], + "Discount Percentage": [ + { + "id": "a4f9c304-8867-4b82-abb6-b968e7ebca3b", + "kind": "dictionaryFeature", + "name": "", + "active": true, + "nGrams": [ + "a" + ], + "caseSensitive": false, + "ignoreDigitIdentity": false, + "ignoreLetterIdentity": false + }, + { + "id": "73f7ba0b-e69e-418e-8483-201bb2fb9c54", + "kind": "dictionaryFeature", + "name": "", + "active": true, + "nGrams": [ + "%" + ], + "caseSensitive": false, + "ignoreDigitIdentity": false, + "ignoreLetterIdentity": false + }, + { + "id": "3e4f9a86-226d-4f4b-af7d-891dc817ee8d", + "kind": "proximityFeature", + "name": "Proximity Between", + "active": true, + "patterns": [ + [ + { + "id": "a4f9c304-8867-4b82-abb6-b968e7ebca3b", + "kind": "proximityFeatureReference" + }, + { + "kind": "proximityTokenRange", + "minCount": 1, + "maxCount": 6 + }, + { + "id": "73f7ba0b-e69e-418e-8483-201bb2fb9c54", + "kind": "proximityFeatureReference" + } + ] + ] + } + ], + "Date of Change": [ + { + "id": "76ba0449-f94c-4b8c-bd9e-abbb89c6ae25", + "kind": "dictionaryFeature", + "name": "Date (numeric)", + "active": true, + "nGrams": [ + "1/1/11", + "1/11/11", + "11/1/11", + "11/11/11", + "1/1/1111", + "1/11/1111", + "11/1/1111", + "11/11/1111", + "1111/1/1", + "1111/1/11", + "1111/11/11", + "1111/11/11" + ], + "caseSensitive": true, + "ignoreDigitIdentity": true, + "ignoreLetterIdentity": false + } + ], + "Date Completed": [ + { + "id": "3f8b332a-abcd-4475-ad80-fbd827e265d4", + "kind": "dictionaryFeature", + "name": "Date (numeric)", + "active": true, + "nGrams": [ + "1/1/11", + "1/11/11", + "11/1/11", + "11/11/11", + "1/1/1111", + "1/11/1111", + "11/1/1111", + "11/11/1111", + "1111/1/1", + "1111/1/11", + "1111/11/11", + "1111/11/11" + ], + "caseSensitive": true, + "ignoreDigitIdentity": true, + "ignoreLetterIdentity": false + } + ], + "Contributor": [ + { + "id": "9abdbfc9-6425-4e03-a344-305d3e60ad7f", + "kind": "dictionaryFeature", + "name": "text", + "active": true, + "nGrams": [ + "Benefit Change Notice" + ], + "caseSensitive": false, + "ignoreDigitIdentity": false, + "ignoreLetterIdentity": false + } + ] + } + }, + "ID": 3, + "LastTrained": "2020-11-03T18:43:53Z", + "ListID": "bc696b17-378c-4347-b509-5d52cc6f3823", + "ModelSettings": null, + "ModelType": 2, + "Modified": "2024-06-27T02:45:32Z", + "ModifiedBy": "i:0#.w|sharepoint\\system", + "ObjectId": "01XHOXSCXFBUHLC2OA7FDJB52PXCWAAE3S", + "PublicationType": 0, + "Schemas": { + "Extractors": { + "Adressee": { + "concepts": { + "0a18ef8b-c0cd-435d-8a45-37738fef4f6f": { + "name": "Adressee" + } + }, + "relationships": [] + }, + "Discount Percentage": { + "concepts": { + "48c09840-d2da-4416-a02d-68113da24d18": { + "name": "Discount Percentage" + } + }, + "relationships": [] + }, + "Date of Change": { + "concepts": { + "f39b4e2a-e945-4a2e-99a0-561334037a66": { + "name": "Date of Change" + } + }, + "relationships": [] + }, + "Date Completed": { + "concepts": { + "3559972a-d7c5-4ccb-b8cb-e4b852da2399": { + "name": "Date Completed" + } + }, + "relationships": [] + }, + "Contributor": { + "concepts": { + "6af8ef33-4bf1-49ca-93d3-7a2358746747": { + "name": "Contributor" + } + }, + "relationships": [] + } + } + }, + "SourceSiteUrl": "https://contoso.sharepoint.com/sites/ContentCenter", + "SourceUrl": null, + "SourceWebServerRelativeUrl": "/sites/ContentCenter", + "UniqueId": "b10e0de5-c069-46f9-90f7-4fb8ac001372", + "Publications": [ + { + "Created": "2020-11-03T12:52:12Z", + "CreatedBy": "i:0#.f|membership|user@contoso.onmicrosoft.com", + "DriveId": "b!7w273MPU8kiqSKc6SWaUkQ3wyRgeHbxDh-e6ShP9X-e-6B-bO36LRI87VfSrxwy9", + "HasTargetSitePermission": true, + "ID": 1, + "ModelId": 3, + "ModelName": "BenefitsChangeNotice.classifier", + "ModelType": 0, + "ModelUniqueId": "b10e0de5-c069-46f9-90f7-4fb8ac001372", + "ModelVersion": "2.0", + "Modified": "2020-11-03T18:45:18Z", + "ModifiedBy": "i:0#.f|membership|user@contoso.onmicrosoft.com", + "ObjectId": "01XHOXSCVXVZCQAAQWCNGK6NGADKKZUMW7", + "PublicationType": 1, + "TargetLibraryId": "7eb6c306-1680-4ba9-9bbe-6b5b7efb27be", + "TargetLibraryName": "Documents", + "TargetLibraryRemoved": false, + "TargetLibraryServerRelativeUrl": "/sites/Spaces/Shared%20Documents", + "TargetLibraryUrl": "https://contoso.sharepoint.com/sites/Spaces/Shared%20Documents", + "TargetSiteId": "7e44de0a-30e3-45ab-a601-057298c9068f", + "TargetSiteUrl": "https://contoso.sharepoint.com/sites/Spaces", + "TargetTableListId": "00000000-0000-0000-0000-000000000000", + "TargetTableListName": null, + "TargetTableListRemoved": false, + "TargetTableListServerRelativeUrl": null, + "TargetTableListUrl": null, + "TargetWebId": "9166df43-8e45-43b8-94ef-3a22826346de", + "TargetWebName": "Spaces", + "TargetWebServerRelativeUrl": "/sites/Spaces", + "UniqueId": "0045aeb7-1602-4c13-af34-c01a959a32df", + "ViewOption": "NewViewAsDefault" + } + ] + } + ``` + + + + + ```text + AIBuilderHybridModelType : null + AzureCognitivePrebuiltModelName: null + BaseContentTypeName : null + ConfidenceScore : {"trainingStatus":{"kind":"original","ClassifierStatus":{"TrainingStatus":"success","TimeStamp":1604429035541},"ExtractorsStatus":[{"TimeStamp":1595871764667,"ExtractorName":"Adressee","TrainingStatus":"success"},{"TimeStamp":1595871896822,"ExtractorName":"Discount Percentage","TrainingStatus":"success"},{"TimeStamp":1595871961934,"ExtractorName":"Date of Change","TrainingStatus":"success"},{"TimeStamp":1604407772191,"ExtractorName":"Date Completed","TrainingStatus":"success"},{"TimeStamp":1604429033385,"ExtractorName":"Contributor","TrainingStatus":"success"}]},"modelAccuracy":{"Classifier":1,"Extractors":{"Adressee":1,"Discount Percentage":1,"Date of Change":1,"Date Completed":1,"Contributor":1}},"perSampleAccuracy":{"43":{"Classifier":1,"Extractors":{"Contributor":1}},"44":{"Classifier":1,"Extractors":{"Contributor":1}},"45":{"Classifier":1,"Extractors":{"Contributor":1}},"48":{"Classifier":1,"Extractors":{"Contributor":1}},"50":{"Classifier":1,"Extractors":{"Contributor":1}},"52":{"Classifier":1,"Extractors":{}}},"perSamplePrediction":{"43":{"Extractors":{"Contributor":["Benefit Change Notice"]}},"44":{"Extractors":{"Contributor":["Benefit Change Notice"]}},"45":{"Extractors":{"Contributor":["Benefit Change Notice"]}},"48":{"Extractors":{"Contributor":["Benefit Change Notice"]}},"50":{"Extractors":{"Contributor":["Benefit Change Notice"]}}},"trainingFailures":{}} + ContentTypeGroup : Intelligent Document Content Types + ContentTypeId : 0x010100B992472522B7C04E9101F1CFD07E4ADC + ContentTypeName : BenefitsChangeNotice + Created : 2020-11-03T12:30:55Z + CreatedBy : i:0#.w|sharepoint\system + DriveId : b!7w273MPU8kiqSKc6SWaUkQ3wyRgeHbxDh-e6ShP9X-cXa2m8jDdHQ7UJXVLMbzgj + Explanations : {"Classifier":[{"id":"24f0b71f-87c6-4f7d-9797-88e9eab00cb6","kind":"dictionaryFeature","name":"Contains \"Benefit Change Notice\"","active":true,"nGrams":["Benefit Change Notice"],"caseSensitive":true,"ignoreDigitIdentity":false,"ignoreLetterIdentity":false},{"id":"849c3ca4-296a-4209-be33-d5be0f942d39","kind":"modelFeature","name":"Adressee","active":true,"modelReference":"Adressee","conceptId":"0a18ef8b-c0cd-435d-8a45-37738fef4f6f"},{"id":"41f80170-c054-42ae-8b30-cd0d9bc35874","kind":"modelFeature","name":"Discount Percentage","active":true,"modelReference":"Discount Percentage","conceptId":"48c09840-d2da-4416-a02d-68113da24d18"},{"id":"c3c46580-5570-4ea7-baa9-69bfc1f9e088","kind":"modelFeature","name":"Date of Change","active":true,"modelReference":"Date of Change","conceptId":"f39b4e2a-e945-4a2e-99a0-561334037a66"},{"id":"e138c9e0-849b-4207-9d5e-3e9925340bb5","kind":"modelFeature","name":"Date Completed","active":true,"modelReference":"Date Completed","conceptId":"3559972a-d7c5-4ccb-b8cb-e4b852da2399"},{"id":"ceb16569-72a4-486a-a7cc-296bad0747c0","kind":"modelFeature","name":"Contributor","active":true,"modelReference":"Contributor","conceptId":"6af8ef33-4bf1-49ca-93d3-7a2358746747"}],"Extractors":{"Adressee":[{"id":"c661eef3-c1cc-4c9f-a4c8-5b617dd46f88","kind":"dictionaryFeature","name":"\"Dear\"","active":true,"nGrams":["Dear"],"caseSensitive":true,"ignoreDigitIdentity":false,"ignoreLetterIdentity":false}],"Discount Percentage":[{"id":"a4f9c304-8867-4b82-abb6-b968e7ebca3b","kind":"dictionaryFeature","name":"\"a\"","active":true,"nGrams":["a"],"caseSensitive":false,"ignoreDigitIdentity":false,"ignoreLetterIdentity":false},{"id":"73f7ba0b-e69e-418e-8483-201bb2fb9c54","kind":"dictionaryFeature","name":"\"%\"","active":true,"nGrams":["%"],"caseSensitive":false,"ignoreDigitIdentity":false,"ignoreLetterIdentity":false},{"id":"3e4f9a86-226d-4f4b-af7d-891dc817ee8d","kind":"proximityFeature","name":"Proximity Between \"a\" and \"%\"","active":true,"patterns":[[{"id":"a4f9c304-8867-4b82-abb6-b968e7ebca3b","kind":"proximityFeatureReference"},{"kind":"proximityTokenRange","minCount":1,"maxCount":6},{"id":"73f7ba0b-e69e-418e-8483-201bb2fb9c54","kind":"proximityFeatureReference"}]]}],"Date of Change":[{"id":"76ba0449-f94c-4b8c-bd9e-abbb89c6ae25","kind":"dictionaryFeature","name":"Date (numeric)","active":true,"nGrams":["1/1/11","1/11/11","11/1/11","11/11/11","1/1/1111","1/11/1111","11/1/1111","11/11/1111","1111/1/1","1111/1/11","1111/11/11","1111/11/11"],"caseSensitive":true,"ignoreDigitIdentity":true,"ignoreLetterIdentity":false}],"Date Completed":[{"id":"3f8b332a-abcd-4475-ad80-fbd827e265d4","kind":"dictionaryFeature","name":"Date (numeric)","active":true,"nGrams":["1/1/11","1/11/11","11/1/11","11/11/11","1/1/1111","1/11/1111","11/1/1111","11/11/1111","1111/1/1","1111/1/11","1111/11/11","1111/11/11"],"caseSensitive":true,"ignoreDigitIdentity":true,"ignoreLetterIdentity":false}],"Contributor":[{"id":"9abdbfc9-6425-4e03-a344-305d3e60ad7f","kind":"dictionaryFeature","name":"text","active":true,"nGrams":["Benefit Change Notice"],"caseSensitive":false,"ignoreDigitIdentity":false,"ignoreLetterIdentity":false}]}} + ID : 3 + LastTrained : 2020-11-03T18:43:53Z + ListID : bc696b17-378c-4347-b509-5d52cc6f3823 + ModelSettings : null + ModelType : 2 + Modified : 2024-06-27T02:45:32Z + ModifiedBy : i:0#.w|sharepoint\system + ObjectId : 01XHOXSCXFBUHLC2OA7FDJB52PXCWAAE3S + PublicationType : 0 + Publications : [{"Created":"2020-11-03T12:52:12Z","CreatedBy":"i:0#.f|membership|user@contoso.onmicrosoft.com","DriveId":"b!7w273MPU8kiqSKc6SWaUkQ3wyRgeHbxDh-e6ShP9X-e-6B-bO36LRI87VfSrxwy9","HasTargetSitePermission":true,"ID":1,"ModelId":3,"ModelName":"BenefitsChangeNotice.classifier","ModelType":0,"ModelUniqueId":"b10e0de5-c069-46f9-90f7-4fb8ac001372","ModelVersion":"2.0","Modified":"2020-11-03T18:45:18Z","ModifiedBy":"i:0#.f|membership|user@contoso.onmicrosoft.com","ObjectId":"01XHOXSCVXVZCQAAQWCNGK6NGADKKZUMW7","PublicationType":1,"TargetLibraryId":"7eb6c306-1680-4ba9-9bbe-6b5b7efb27be","TargetLibraryName":"Documents","TargetLibraryRemoved":false,"TargetLibraryServerRelativeUrl":"/sites/Spaces/Shared%20Documents","TargetLibraryUrl":"https://contoso.sharepoint.com/sites/Spaces/Shared%20Documents","TargetSiteId":"7e44de0a-30e3-45ab-a601-057298c9068f","TargetSiteUrl":"https://contoso.sharepoint.com/sites/Spaces","TargetTableListId":"00000000-0000-0000-0000-000000000000","TargetTableListName":null,"TargetTableListRemoved":false,"TargetTableListServerRelativeUrl":null,"TargetTableListUrl":null,"TargetWebId":"9166df43-8e45-43b8-94ef-3a22826346de","TargetWebName":"Spaces","TargetWebServerRelativeUrl":"/sites/Spaces","UniqueId":"0045aeb7-1602-4c13-af34-c01a959a32df","ViewOption":"NewViewAsDefault"}] + Schemas : {"Extractors":{"Adressee":{"concepts":{"0a18ef8b-c0cd-435d-8a45-37738fef4f6f":{"name":"Adressee"}},"relationships":[]},"Discount Percentage":{"concepts":{"48c09840-d2da-4416-a02d-68113da24d18":{"name":"Discount Percentage"}},"relationships":[]},"Date of Change":{"concepts":{"f39b4e2a-e945-4a2e-99a0-561334037a66":{"name":"Date of Change"}},"relationships":[]},"Date Completed":{"concepts":{"3559972a-d7c5-4ccb-b8cb-e4b852da2399":{"name":"Date Completed"}},"relationships":[]},"Contributor":{"concepts":{"6af8ef33-4bf1-49ca-93d3-7a2358746747":{"name":"Contributor"}},"relationships":[]}}} + SourceSiteUrl : https://contoso.sharepoint.com/sites/ContentCenter + SourceUrl : null + SourceWebServerRelativeUrl : /sites/ContentCenter + UniqueId : b10e0de5-c069-46f9-90f7-4fb8ac001372 + ``` + + + + + ```csv + AIBuilderHybridModelType,AzureCognitivePrebuiltModelName,BaseContentTypeName,ContentTypeGroup,ContentTypeId,ContentTypeName,Created,CreatedBy,DriveId,ID,LastTrained,ListID,ModelName,ModelType,Modified,ModifiedBy,ObjectId,PublicationType,SourceSiteUrl,SourceUrl,SourceWebServerRelativeUrl,UniqueId + ,,,Intelligent Document Content Types,0x010100B992472522B7C04E9101F1CFD07E4ADC,BenefitsChangeNotice,2020-11-03T12:30:55Z,i:0#.w|sharepoint\system,b!7w273MPU8kiqSKc6SWaUkQ3wyRgeHbxDh-e6ShP9X-cXa2m8jDdHQ7UJXVLMbzgj,3,2020-11-03T18:43:53Z,bc696b17-378c-4347-b509-5d52cc6f3823,BenefitsChangeNotice,2,2024-11-08T04:49:57Z,i:0#.w|sharepoint\system,01XHOXSCXFBUHLC2OA7FDJB52PXCWAAE3S,0,https://contoso.sharepoint.com/sites/ContentCenter,,/sites/ContentCenter,b10e0de5-c069-46f9-90f7-4fb8ac001372 + ``` + + + + + ```md + # spp model get --siteUrl "https://contoso.sharepoint.com/sites/ContentCenter" --id "b10e0de5-c069-46f9-90f7-4fb8ac001372" --withPublications "true" + + Date: 29/09/2024 + + ## 3 + + Property | Value + ---------|------- + ContentTypeGroup | Intelligent Document Content Types + ContentTypeId | 0x010100B992472522B7C04E9101F1CFD07E4ADC + ContentTypeName | BenefitsChangeNotice + Created | 2020-11-03T12:30:55Z + CreatedBy | i:0#.w\|sharepoint\system + DriveId | b!7w273MPU8kiqSKc6SWaUkQ3wyRgeHbxDh-e6ShP9X-cXa2m8jDdHQ7UJXVLMbzgj + ID | 3 + LastTrained | 2020-11-03T18:43:53Z + ListID | bc696b17-378c-4347-b509-5d52cc6f3823 + ModelName | BenefitsChangeNotice + ModelType | 2 + Modified | 2024-11-08T04:49:57Z + ModifiedBy | i:0#.w\|sharepoint\system + ObjectId | 01XHOXSCXFBUHLC2OA7FDJB52PXCWAAE3S + PublicationType | 0 + SourceSiteUrl | https://contoso.sharepoint.com/sites/ContentCenter + SourceWebServerRelativeUrl | /sites/ContentCenter + UniqueId | b10e0de5-c069-46f9-90f7-4fb8ac001372 + ``` + + + diff --git a/docs/src/config/sidebars.ts b/docs/src/config/sidebars.ts index 06ed8558b56..c564bc50359 100644 --- a/docs/src/config/sidebars.ts +++ b/docs/src/config/sidebars.ts @@ -3989,6 +3989,11 @@ const sidebars: SidebarsConfig = { }, { model: [ + { + type: 'doc', + label: 'model get', + id: 'cmd/spp/model/model-get' + }, { type: 'doc', label: 'model list', diff --git a/src/m365/spp/commands.ts b/src/m365/spp/commands.ts index a657043c662..8fbe4308a36 100644 --- a/src/m365/spp/commands.ts +++ b/src/m365/spp/commands.ts @@ -2,6 +2,7 @@ const prefix: string = 'spp'; export default { CONTENTCENTER_LIST: `${prefix} contentcenter list`, + MODEL_GET: `${prefix} model get`, MODEL_LIST: `${prefix} model list`, MODEL_REMOVE: `${prefix} model remove` }; \ No newline at end of file diff --git a/src/m365/spp/commands/model/model-get.spec.ts b/src/m365/spp/commands/model/model-get.spec.ts new file mode 100644 index 00000000000..11c38cc9ee9 --- /dev/null +++ b/src/m365/spp/commands/model/model-get.spec.ts @@ -0,0 +1,379 @@ +import assert from 'assert'; +import sinon from 'sinon'; +import auth from '../../../../Auth.js'; +import { cli } from '../../../../cli/cli.js'; +import { CommandInfo } from '../../../../cli/CommandInfo.js'; +import { Logger } from '../../../../cli/Logger.js'; +import { CommandError } from '../../../../Command.js'; +import request from '../../../../request.js'; +import { telemetry } from '../../../../telemetry.js'; +import { pid } from '../../../../utils/pid.js'; +import { session } from '../../../../utils/session.js'; +import { sinonUtil } from '../../../../utils/sinonUtil.js'; +import commands from '../../commands.js'; +import command from './model-get.js'; +import { spp } from '../../../../utils/spp.js'; + +describe(commands.MODEL_GET, () => { + let log: string[]; + let logger: Logger; + let loggerLogSpy: sinon.SinonSpy; + let commandInfo: CommandInfo; + const model = { + "AIBuilderHybridModelType": null, + "AzureCognitivePrebuiltModelName": null, + "BaseContentTypeName": null, + "ConfidenceScore": "{\"trainingStatus\":{\"kind\":\"original\",\"ClassifierStatus\":{\"TrainingStatus\":\"success\",\"TimeStamp\":1716547860981},\"ExtractorsStatus\":[{\"TimeStamp\":1716547860173,\"ExtractorName\":\"Name\",\"TrainingStatus\":\"success\"}]},\"modelAccuracy\":{\"Classifier\":1,\"Extractors\":{\"Name\":0.333333343}},\"perSampleAccuracy\":{\"1\":{\"Classifier\":1,\"Extractors\":{\"Name\":1}},\"2\":{\"Classifier\":1,\"Extractors\":{\"Name\":0}},\"3\":{\"Classifier\":1,\"Extractors\":{\"Name\":0}},\"4\":{\"Classifier\":1,\"Extractors\":{\"Name\":0}},\"5\":{\"Classifier\":1,\"Extractors\":{\"Name\":0}},\"6\":{\"Classifier\":1,\"Extractors\":{\"Name\":1}}},\"perSamplePrediction\":{\"1\":{\"Extractors\":{\"Name\":[\"FirstName\"]}},\"2\":{\"Extractors\":{\"Name\":[]}},\"3\":{\"Extractors\":{\"Name\":[]}},\"4\":{\"Extractors\":{\"Name\":[]}},\"5\":{\"Extractors\":{\"Name\":[]}},\"6\":{\"Extractors\":{\"Name\":[]}}},\"trainingFailures\":{}}", + "ContentTypeGroup": "Intelligent Document Content Types", + "ContentTypeId": "0x010100A5C3671D1FB1A64D9F280C628D041692", + "ContentTypeName": "TeachingModel", + "Created": "2024-05-23T16:51:29Z", + "CreatedBy": "i:0#.f|membership|user@contoso.onmicrosoft.com", + "DriveId": "b!qTVLltt1P02LUgejOy6O_1amoFeu1EJBlawH83UtYbQs_H3KVKAcQpuQOpNLl646", + "Explanations": "{\"Classifier\":[{\"id\":\"950f39cd-5e72-4442-ae8a-ea4bae32962c\",\"kind\":\"regexFeature\",\"name\":\"Email address\",\"active\":true,\"pattern\":\"[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,6}\"},{\"id\":\"d3f2940d-1df1-4ba8-975a-db3a4d626d5c\",\"kind\":\"dictionaryFeature\",\"name\":\"FirstName\",\"active\":true,\"nGrams\":[\"FirstName\"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false},{\"id\":\"077966e1-73be-44c9-855f-a4eade6a280b\",\"kind\":\"modelFeature\",\"name\":\"Name\",\"active\":true,\"modelReference\":\"Name\",\"conceptId\":\"309b64e5-acd5-4538-a5b6-c6bfcdc1ffbf\"}],\"Extractors\":{\"Name\":[{\"id\":\"69e412bc-e5bc-4657-b378-34a01966bb92\",\"kind\":\"dictionaryFeature\",\"name\":\"Before label\",\"active\":true,\"nGrams\":[\"Test\",\"'Surname\",\"Test (\"],\"caseSensitive\":false,\"ignoreDigitIdentity\":false,\"ignoreLetterIdentity\":false}]}}", + "ID": 1, + "LastTrained": "2024-05-24T17:51:16Z", + "ListID": "ca7dfc2c-a054-421c-9b90-3a934b97ae3a", + "ModelSettings": "{\"ModelOrigin\":{\"LibraryId\":\"8a6027ab-c584-4394-ba9c-3dc4dd152b65\",\"Published\":false,\"SelecteFileUniqueIds\":[]}}", + "ModelType": 2, + "Modified": "2024-05-24T17:51:02Z", + "ModifiedBy": "i:0#.f|membership|user@contoso.onmicrosoft.com", + "ObjectId": "01HQDCWVGIEBDRN3RVK5A3UJW3M4TCMT45", + "PublicationType": 0, + "Schemas": "{\"Version\":2,\"Extractors\":{\"Name\":{\"concepts\":{\"309b64e5-acd5-4538-a5b6-c6bfcdc1ffbf\":{\"name\":\"Name\"}},\"relationships\":[],\"id\":\"Name\"}}}", + "SourceSiteUrl": "https://contoso.sharepoint.com/sites/SyntexTest", + "SourceUrl": null, + "SourceWebServerRelativeUrl": "/sites/SyntexTest", + "UniqueId": "164720c8-35ee-4157-ba26-db6726264f9d" + }; + + const modelWithoutAdditionalData = { + "AIBuilderHybridModelType": null, + "AzureCognitivePrebuiltModelName": null, + "BaseContentTypeName": null, + "ConfidenceScore": null, + "ContentTypeGroup": "Intelligent Document Content Types", + "ContentTypeId": "0x010100A5C3671D1FB1A64D9F280C628D041692", + "ContentTypeName": "TeachingModel", + "Created": "2024-05-23T16:51:29Z", + "CreatedBy": "i:0#.f|membership|user@contoso.onmicrosoft.com", + "DriveId": "b!qTVLltt1P02LUgejOy6O_1amoFeu1EJBlawH83UtYbQs_H3KVKAcQpuQOpNLl646", + "Explanations": null, + "ID": 1, + "LastTrained": "2024-05-24T17:51:16Z", + "ListID": "ca7dfc2c-a054-421c-9b90-3a934b97ae3a", + "ModelSettings": null, + "ModelType": 2, + "Modified": "2024-05-24T17:51:02Z", + "ModifiedBy": "i:0#.f|membership|user@contoso.onmicrosoft.com", + "ObjectId": "01HQDCWVGIEBDRN3RVK5A3UJW3M4TCMT45", + "PublicationType": 0, + "Schemas": null, + "SourceSiteUrl": "https://contoso.sharepoint.com/sites/SyntexTest", + "SourceUrl": null, + "SourceWebServerRelativeUrl": "/sites/SyntexTest", + "UniqueId": "164720c8-35ee-4157-ba26-db6726264f9d" + }; + + const modelResult = { + "AIBuilderHybridModelType": null, + "AzureCognitivePrebuiltModelName": null, + "BaseContentTypeName": null, + "ConfidenceScore": { "trainingStatus": { "kind": "original", "ClassifierStatus": { "TrainingStatus": "success", "TimeStamp": 1716547860981 }, "ExtractorsStatus": [{ "TimeStamp": 1716547860173, "ExtractorName": "Name", "TrainingStatus": "success" }] }, "modelAccuracy": { "Classifier": 1, "Extractors": { "Name": 0.333333343 } }, "perSampleAccuracy": { "1": { "Classifier": 1, "Extractors": { "Name": 1 } }, "2": { "Classifier": 1, "Extractors": { "Name": 0 } }, "3": { "Classifier": 1, "Extractors": { "Name": 0 } }, "4": { "Classifier": 1, "Extractors": { "Name": 0 } }, "5": { "Classifier": 1, "Extractors": { "Name": 0 } }, "6": { "Classifier": 1, "Extractors": { "Name": 1 } } }, "perSamplePrediction": { "1": { "Extractors": { "Name": ["FirstName"] } }, "2": { "Extractors": { "Name": [] } }, "3": { "Extractors": { "Name": [] } }, "4": { "Extractors": { "Name": [] } }, "5": { "Extractors": { "Name": [] } }, "6": { "Extractors": { "Name": [] } } }, "trainingFailures": {} }, + "ContentTypeGroup": "Intelligent Document Content Types", + "ContentTypeId": "0x010100A5C3671D1FB1A64D9F280C628D041692", + "ContentTypeName": "TeachingModel", + "Created": "2024-05-23T16:51:29Z", + "CreatedBy": "i:0#.f|membership|user@contoso.onmicrosoft.com", + "DriveId": "b!qTVLltt1P02LUgejOy6O_1amoFeu1EJBlawH83UtYbQs_H3KVKAcQpuQOpNLl646", + "Explanations": { "Classifier": [{ "id": "950f39cd-5e72-4442-ae8a-ea4bae32962c", "kind": "regexFeature", "name": "Email address", "active": true, "pattern": "[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,6}" }, { "id": "d3f2940d-1df1-4ba8-975a-db3a4d626d5c", "kind": "dictionaryFeature", "name": "FirstName", "active": true, "nGrams": ["FirstName"], "caseSensitive": false, "ignoreDigitIdentity": false, "ignoreLetterIdentity": false }, { "id": "077966e1-73be-44c9-855f-a4eade6a280b", "kind": "modelFeature", "name": "Name", "active": true, "modelReference": "Name", "conceptId": "309b64e5-acd5-4538-a5b6-c6bfcdc1ffbf" }], "Extractors": { "Name": [{ "id": "69e412bc-e5bc-4657-b378-34a01966bb92", "kind": "dictionaryFeature", "name": "Before label", "active": true, "nGrams": ["Test", "'Surname", "Test ("], "caseSensitive": false, "ignoreDigitIdentity": false, "ignoreLetterIdentity": false }] } }, + "ID": 1, + "LastTrained": "2024-05-24T17:51:16Z", + "ListID": "ca7dfc2c-a054-421c-9b90-3a934b97ae3a", + "ModelSettings": { "ModelOrigin": { "LibraryId": "8a6027ab-c584-4394-ba9c-3dc4dd152b65", "Published": false, "SelecteFileUniqueIds": [] } }, + "ModelType": 2, + "Modified": "2024-05-24T17:51:02Z", + "ModifiedBy": "i:0#.f|membership|user@contoso.onmicrosoft.com", + "ObjectId": "01HQDCWVGIEBDRN3RVK5A3UJW3M4TCMT45", + "PublicationType": 0, + "Schemas": { "Version": 2, "Extractors": { "Name": { "concepts": { "309b64e5-acd5-4538-a5b6-c6bfcdc1ffbf": { "name": "Name" } }, "relationships": [], "id": "Name" } } }, + "SourceSiteUrl": "https://contoso.sharepoint.com/sites/SyntexTest", + "SourceUrl": null, + "SourceWebServerRelativeUrl": "/sites/SyntexTest", + "UniqueId": "164720c8-35ee-4157-ba26-db6726264f9d" + }; + + const modelResultWithoutAdditionalData = { + "AIBuilderHybridModelType": null, + "AzureCognitivePrebuiltModelName": null, + "BaseContentTypeName": null, + "ConfidenceScore": null, + "ContentTypeGroup": "Intelligent Document Content Types", + "ContentTypeId": "0x010100A5C3671D1FB1A64D9F280C628D041692", + "ContentTypeName": "TeachingModel", + "Created": "2024-05-23T16:51:29Z", + "CreatedBy": "i:0#.f|membership|user@contoso.onmicrosoft.com", + "DriveId": "b!qTVLltt1P02LUgejOy6O_1amoFeu1EJBlawH83UtYbQs_H3KVKAcQpuQOpNLl646", + "Explanations": null, + "ID": 1, + "LastTrained": "2024-05-24T17:51:16Z", + "ListID": "ca7dfc2c-a054-421c-9b90-3a934b97ae3a", + "ModelSettings": null, + "ModelType": 2, + "Modified": "2024-05-24T17:51:02Z", + "ModifiedBy": "i:0#.f|membership|user@contoso.onmicrosoft.com", + "ObjectId": "01HQDCWVGIEBDRN3RVK5A3UJW3M4TCMT45", + "PublicationType": 0, + "SourceSiteUrl": "https://contoso.sharepoint.com/sites/SyntexTest", + "Schemas": null, + "SourceUrl": null, + "SourceWebServerRelativeUrl": "/sites/SyntexTest", + "UniqueId": "164720c8-35ee-4157-ba26-db6726264f9d" + }; + + const publications = [ + { + "Created": "2020-11-03T12:52:12Z", + "CreatedBy": "i:0#.f|membership|user@contoso.onmicrosoft.com", + "DriveId": "b!7w273MPU8kiqSKc6SWaUkQ3wyRgeHbxDh-e6ShP9X-e-6B-bO36LRI87VfSrxwy9", + "HasTargetSitePermission": true, + "ID": 1, + "ModelId": 3, + "ModelName": "BenefitsChangeNotice.classifier", + "ModelType": 0, + "ModelUniqueId": "b10e0de5-c069-46f9-90f7-4fb8ac001372", + "ModelVersion": "2.0", + "Modified": "2020-11-03T18:45:18Z", + "ModifiedBy": "i:0#.f|membership|user@contoso.onmicrosoft.com", + "ObjectId": "01XHOXSCVXVZCQAAQWCNGK6NGADKKZUMW7", + "PublicationType": 1, + "TargetLibraryId": "7eb6c306-1680-4ba9-9bbe-6b5b7efb27be", + "TargetLibraryName": "Documents", + "TargetLibraryRemoved": false, + "TargetLibraryServerRelativeUrl": "/sites/SyntexTest/Shared%20Documents", + "TargetLibraryUrl": "https://contoso.sharepoint.com/sites/SyntexTest/Shared%20Documents", + "TargetSiteId": "7e44de0a-30e3-45ab-a601-057298c9068f", + "TargetSiteUrl": "https://contoso.sharepoint.com/sites/SyntexTest", + "TargetTableListId": "00000000-0000-0000-0000-000000000000", + "TargetTableListName": null, + "TargetTableListRemoved": false, + "TargetTableListServerRelativeUrl": null, + "TargetTableListUrl": null, + "TargetWebId": "9166df43-8e45-43b8-94ef-3a22826346de", + "TargetWebName": "SyntexTest", + "TargetWebServerRelativeUrl": "/sites/SyntexTest", + "UniqueId": "0045aeb7-1602-4c13-af34-c01a959a32df", + "ViewOption": "NewViewAsDefault" + } + ]; + + before(() => { + sinon.stub(auth, 'restoreAuth').resolves(); + sinon.stub(telemetry, 'trackEvent').returns(); + sinon.stub(pid, 'getProcessName').returns(''); + sinon.stub(session, 'getId').returns(''); + sinon.stub(spp, 'assertSiteIsContentCenter').resolves(); + auth.connection.active = true; + commandInfo = cli.getCommandInfo(command); + }); + + beforeEach(() => { + log = []; + logger = { + log: async (msg: string) => { + log.push(msg); + }, + logRaw: async (msg: string) => { + log.push(msg); + }, + logToStderr: async (msg: string) => { + log.push(msg); + } + }; + loggerLogSpy = sinon.spy(logger, 'log'); + }); + + afterEach(() => { + sinonUtil.restore([ + request.get + ]); + }); + + after(() => { + sinon.restore(); + auth.connection.active = false; + }); + + it('has correct name', () => { + assert.strictEqual(command.name, commands.MODEL_GET); + }); + + it('has a description', () => { + assert.notStrictEqual(command.description, null); + }); + + it('passes validation when required parameters are valid with id', async () => { + const actual = await command.validate({ options: { siteUrl: 'https://contoso.sharepoint.com/sites/sales', id: '9b1b1e42-794b-4c71-93ac-5ed92488b67f' } }, commandInfo); + assert.strictEqual(actual, true); + }); + + it('passes validation when required parameters are valid with title', async () => { + const actual = await command.validate({ options: { siteUrl: 'https://contoso.sharepoint.com/sites/sales', title: 'ModelName' } }, commandInfo); + assert.strictEqual(actual, true); + }); + + it('passes validation when required parameters are valid with id and withPublications', async () => { + const actual = await command.validate({ options: { siteUrl: 'https://contoso.sharepoint.com/sites/sales', id: '9b1b1e42-794b-4c71-93ac-5ed92488b67f', withPublications: true } }, commandInfo); + assert.strictEqual(actual, true); + }); + + it('passes validation when required parameters are valid with title and withPublications', async () => { + const actual = await command.validate({ options: { siteUrl: 'https://contoso.sharepoint.com/sites/sales', title: 'ModelName', withPublications: true } }, commandInfo); + assert.strictEqual(actual, true); + }); + + it('fails validation when siteUrl is not valid', async () => { + const actual = await command.validate({ options: { siteUrl: 'invalidUrl', id: '9b1b1e42-794b-4c71-93ac-5ed92488b67f' } }, commandInfo); + assert.notStrictEqual(actual, true); + }); + + it('fails validation when id is not valid', async () => { + const actual = await command.validate({ options: { siteUrl: 'https://contoso.sharepoint.com/sites/sales', id: 'foo' } }, commandInfo); + assert.notStrictEqual(actual, true); + }); + + it('correctly handles a model is not found error by id', async () => { + sinon.stub(request, 'get').callsFake(async (opts) => { + if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/models/getbyuniqueid('9b1b1e42-794b-4c71-93ac-5ed92488b67f')`) { + throw { + error: { + "odata.error": { + code: "-1, Microsoft.Office.Server.ContentCenter.ModelNotFoundException", + message: { + lang: "en-US", + value: "File Not Found." + } + } + } + }; + } + }); + + await assert.rejects(command.action(logger, { options: { verbose: true, siteUrl: 'https://contoso.sharepoint.com/sites/portal', id: '9b1b1e42-794b-4c71-93ac-5ed92488b67f' } }), + new CommandError('File Not Found.')); + }); + + it('correctly handles a model is not found error by title', async () => { + sinon.stub(request, 'get').callsFake(async (opts) => { + if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/models/getbytitle('invalidtitle.classifier')`) { + return { + "odata.null": true + }; + } + + throw 'Invalid request'; + }); + + await assert.rejects(command.action(logger, { options: { verbose: true, siteUrl: 'https://contoso.sharepoint.com/sites/portal', title: 'invalidTitle' } }), + new CommandError('Model not found.')); + }); + + it('retrieves model by id', async () => { + sinon.stub(request, 'get').callsFake(async (opts) => { + if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/models/getbyuniqueid('9b1b1e42-794b-4c71-93ac-5ed92488b67f')`) { + return model; + } + + throw 'Invalid request'; + }); + + await command.action(logger, { options: { siteUrl: 'https://contoso.sharepoint.com/sites/portal', id: '9b1b1e42-794b-4c71-93ac-5ed92488b67f' } }); + assert.deepStrictEqual(loggerLogSpy.lastCall.args[0], modelResult); + }); + + it('retrieves model by title', async () => { + sinon.stub(request, 'get').callsFake(async (opts) => { + if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/models/getbytitle('modelname.classifier')`) { + return model; + } + + throw 'Invalid request'; + }); + + await command.action(logger, { options: { siteUrl: 'https://contoso.sharepoint.com/sites/portal', title: 'ModelName' } }); + assert.deepStrictEqual(loggerLogSpy.lastCall.args[0], modelResult); + }); + + it('retrieves model without additional information by title', async () => { + sinon.stub(request, 'get').callsFake(async (opts) => { + if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/models/getbytitle('modelname.classifier')`) { + return modelWithoutAdditionalData; + } + + throw 'Invalid request'; + }); + + await command.action(logger, { options: { siteUrl: 'https://contoso.sharepoint.com/sites/portal', title: 'ModelName' } }); + assert.deepStrictEqual(loggerLogSpy.lastCall.args[0], modelResultWithoutAdditionalData); + }); + + it('retrieves model by title with classifier suffix', async () => { + sinon.stub(request, 'get').callsFake(async (opts) => { + if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/models/getbytitle('modelname.classifier')`) { + return model; + } + + throw 'Invalid request'; + }); + + await command.action(logger, { options: { siteUrl: 'https://contoso.sharepoint.com/sites/portal', title: 'ModelName.classifier' } }); + assert.deepStrictEqual(loggerLogSpy.lastCall.args[0], modelResult); + }); + + it('gets correct model when the site URL has a trailing slash', async () => { + sinon.stub(request, 'get').callsFake(async (opts) => { + if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/models/getbyuniqueid('9b1b1e42-794b-4c71-93ac-5ed92488b67f')`) { + return model; + } + + throw 'Invalid request'; + }); + + await command.action(logger, { options: { siteUrl: 'https://contoso.sharepoint.com/sites/portal/', id: '9b1b1e42-794b-4c71-93ac-5ed92488b67f' } }); + assert.deepStrictEqual(loggerLogSpy.lastCall.args[0], modelResult); + }); + + it('retrieves model by id with withPublications', async () => { + sinon.stub(request, 'get').callsFake(async (opts) => { + if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/models/getbyuniqueid('164720c8-35ee-4157-ba26-db6726264f9d')`) { + return model; + } + + if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/publications/getbymodeluniqueid('164720c8-35ee-4157-ba26-db6726264f9d')`) { + return { value: publications }; + } + + throw 'Invalid request'; + }); + + await command.action(logger, { options: { siteUrl: 'https://contoso.sharepoint.com/sites/portal', id: '164720c8-35ee-4157-ba26-db6726264f9d', withPublications: true } }); + assert.deepStrictEqual(loggerLogSpy.lastCall.args[0], { ...modelResult, Publications: publications }); + }); + + it('retrieves model by title with withPublications', async () => { + sinon.stub(request, 'get').callsFake(async (opts) => { + if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/models/getbytitle('modelname.classifier')`) { + return model; + } + + if (opts.url === `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/publications/getbymodeluniqueid('164720c8-35ee-4157-ba26-db6726264f9d')`) { + return { value: publications }; + } + + throw 'Invalid request'; + }); + + await command.action(logger, { options: { siteUrl: 'https://contoso.sharepoint.com/sites/portal', title: 'ModelName', withPublications: true } }); + assert.deepStrictEqual(loggerLogSpy.lastCall.args[0], { ...modelResult, Publications: publications }); + }); +}); \ No newline at end of file diff --git a/src/m365/spp/commands/model/model-get.ts b/src/m365/spp/commands/model/model-get.ts new file mode 100644 index 00000000000..4f009a2496b --- /dev/null +++ b/src/m365/spp/commands/model/model-get.ts @@ -0,0 +1,146 @@ +import { Logger } from '../../../../cli/Logger.js'; +import GlobalOptions from '../../../../GlobalOptions.js'; +import request, { CliRequestOptions } from '../../../../request.js'; +import { formatting } from '../../../../utils/formatting.js'; +import { odata } from '../../../../utils/odata.js'; +import { spp, SppModel } from '../../../../utils/spp.js'; +import { urlUtil } from '../../../../utils/urlUtil.js'; +import { validation } from '../../../../utils/validation.js'; +import SpoCommand from '../../../base/SpoCommand.js'; +import commands from '../../commands.js'; + +interface CommandArgs { + options: Options; +} + +interface Options extends GlobalOptions { + siteUrl: string; + id?: string; + title?: string; + withPublications?: boolean; +} + +class SppModelGetCommand extends SpoCommand { + public get name(): string { + return commands.MODEL_GET; + } + + public get description(): string { + return 'Retrieves information about a document understanding model'; + } + + constructor() { + super(); + + this.#initTelemetry(); + this.#initOptions(); + this.#initValidators(); + this.#initOptionSets(); + this.#initTypes(); + } + + #initTelemetry(): void { + this.telemetry.push((args: CommandArgs) => { + Object.assign(this.telemetryProperties, { + id: typeof args.options.id !== 'undefined', + title: typeof args.options.title !== 'undefined', + withPublications: !!args.options.withPublications + }); + }); + } + + #initOptions(): void { + this.options.unshift( + { + option: '-u, --siteUrl ' + }, + { + option: '-i, --id [id]' + }, + { + option: '-t, --title [title]' + }, + { + option: '--withPublications' + } + ); + } + + #initValidators(): void { + this.validators.push( + async (args: CommandArgs) => { + if (args.options.id && !validation.isValidGuid(args.options.id)) { + return `${args.options.id} is not a valid GUID for option 'id'.`; + } + + return validation.isValidSharePointUrl(args.options.siteUrl); + } + ); + } + + #initOptionSets(): void { + this.optionSets.push({ options: ['id', 'title'] }); + } + + #initTypes(): void { + this.types.string.push('siteUrl', 'id', 'title'); + this.types.boolean.push('withPublications'); + } + + public async commandAction(logger: Logger, args: CommandArgs): Promise { + try { + if (this.verbose) { + await logger.log(`Retrieving model information from ${args.options.siteUrl}...`); + } + + const siteUrl = urlUtil.removeTrailingSlashes(args.options.siteUrl); + await spp.assertSiteIsContentCenter(siteUrl); + + let requestUrl = `${siteUrl}/_api/machinelearning/models/`; + + if (args.options.title) { + let requestTitle = args.options.title.toLowerCase(); + + if (!requestTitle.endsWith('.classifier')) { + requestTitle += '.classifier'; + } + + requestUrl += `getbytitle('${formatting.encodeQueryParameter(requestTitle)}')`; + } + else { + requestUrl += `getbyuniqueid('${args.options.id}')`; + } + + const requestOptions: CliRequestOptions = { + url: requestUrl, + headers: { + accept: 'application/json;odata=nometadata' + }, + responseType: 'json' + }; + + const result = await request.get(requestOptions); + + if ((result as any)['odata.null'] === true) { + throw 'Model not found.'; + } + + if (args.options.withPublications) { + result.Publications = await odata.getAllItems(`${siteUrl}/_api/machinelearning/publications/getbymodeluniqueid('${result.UniqueId}')`); + } + + await logger.log({ + ...result, + ConfidenceScore: result.ConfidenceScore ? JSON.parse(result.ConfidenceScore) : null, + Explanations: result.Explanations ? JSON.parse(result.Explanations) : null, + Schemas: result.Schemas ? JSON.parse(result.Schemas) : null, + ModelSettings: result.ModelSettings ? JSON.parse(result.ModelSettings) : null + }); + } + catch (err: any) { + this.handleRejectedODataJsonPromise(err); + } + } +} + +export default new SppModelGetCommand(); \ No newline at end of file diff --git a/src/utils/spp.ts b/src/utils/spp.ts index 0b6dff3454b..b52e024715c 100644 --- a/src/utils/spp.ts +++ b/src/utils/spp.ts @@ -1,8 +1,12 @@ import request, { CliRequestOptions } from '../request.js'; export interface SppModel { + ConfidenceScore?: string; + Explanations?: string; + Schemas?: string; UniqueId: string; Publications?: any[]; + ModelSettings?: string; } export const spp = {