@mmerterden/multi-agent-pipeline 20.7.0 → 20.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/LICENSE +0 -10
- package/docs/facts.json +1 -1
- package/manifest.json +266 -267
- package/package.json +2 -2
- package/pipeline/scripts/_notices.mjs +1 -1
- package/pipeline/skills/.skill-manifest.json +68 -68
- package/pipeline/skills/shared/README.md +70 -70
- package/pipeline/skills/shared/external/alarmkit/SKILL.md +373 -381
- package/pipeline/skills/shared/external/alarmkit/evals/evals.json +23 -18
- package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +328 -378
- package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
- package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
- package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
- package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
- package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
- package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
- package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
- package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +339 -277
- package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
- package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +105 -122
- package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +143 -166
- package/pipeline/skills/shared/external/app-store-review/SKILL.md +307 -326
- package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
- package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
- package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +333 -360
- package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
- package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
- package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
- package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
- package/pipeline/skills/shared/external/authentication/SKILL.md +265 -381
- package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
- package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +133 -178
- package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
- package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
- package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
- package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
- package/pipeline/skills/shared/external/background-processing/SKILL.md +270 -382
- package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
- package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +169 -317
- package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
- package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
- package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
- package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
- package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
- package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
- package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
- package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
- package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +226 -376
- package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
- package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
- package/pipeline/skills/shared/external/core-data/SKILL.md +292 -368
- package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
- package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
- package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
- package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
- package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
- package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
- package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
- package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
- package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
- package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
- package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
- package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
- package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
- package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
- package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
- package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
- package/pipeline/skills/shared/external/device-integrity/SKILL.md +230 -353
- package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
- package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
- package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
- package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
- package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
- package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
- package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
- package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
- package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
- package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
- package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
- package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
- package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
- package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
- package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
- package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
- package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
- package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
- package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
- package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
- package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
- package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
- package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
- package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
- package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
- package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
- package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
- package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
- package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
- package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
- package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
- package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
- package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
- package/pipeline/skills/shared/external/mapkit-location/SKILL.md +295 -267
- package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
- package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
- package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
- package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
- package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
- package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
- package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
- package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
- package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
- package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
- package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
- package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
- package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
- package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
- package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
- package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
- package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
- package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
- package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
- package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
- package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
- package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
- package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
- package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
- package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
- package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
- package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
- package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
- package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
- package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
- package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
- package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
- package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
- package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
- package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
- package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
- package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
- package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
- package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
- package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
- package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
- package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
- package/pipeline/skills/shared/external/storekit/references/core-patterns.md +298 -242
- package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
- package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
- package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
- package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
- package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
- package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
- package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
- package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
- package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
- package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +303 -351
- package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
- package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
- package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
- package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
- package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
- package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
- package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
- package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
- package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
- package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
- package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
- package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
- package/pipeline/skills/shared/external/swift-security/SKILL.md +180 -161
- package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
- package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
- package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +408 -476
- package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
- package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
- package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
- package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
- package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
- package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
- package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +352 -472
- package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
- package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
- package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
- package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +396 -457
- package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
- package/pipeline/skills/shared/external/swift-testing/SKILL.md +188 -175
- package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
- package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +80 -84
- package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
- package/pipeline/skills/shared/external/swiftdata/SKILL.md +392 -256
- package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
- package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
- package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
- package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
- package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
- package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
- package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
- package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
- package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
- package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
- package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
- package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
- package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
- package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
- package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
- package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
- package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
- package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
- package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
- package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
- package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
- package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
- package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
- package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +193 -168
- package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
- package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +132 -133
- package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
- package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +106 -140
- package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
- package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
- package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
- package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
- package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
- package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
- package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
- package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
- package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
- package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
- package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
- package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
- package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
- package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
- package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
- package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
- package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
- package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
- package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
- package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
- package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
- package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
- package/pipeline/skills/shared/external/weatherkit/SKILL.md +152 -310
- package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
- package/pipeline/skills/shared/external/widgetkit/SKILL.md +216 -288
- package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +414 -719
- package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +0 -39
|
@@ -4,43 +4,43 @@
|
|
|
4
4
|
{
|
|
5
5
|
"id": 0,
|
|
6
6
|
"name": "text-analysis-pipeline",
|
|
7
|
-
"prompt": "
|
|
8
|
-
"expected_output": "
|
|
7
|
+
"prompt": "Our support inbox app receives short customer messages in many languages. For each message we want the language, any people, places and companies mentioned, an overall mood score, and a list of similar past keywords. Processing runs on a background queue with several workers. Design the NaturalLanguage side.",
|
|
8
|
+
"expected_output": "Picks sensible token units, keeps every NLTokenizer and NLTagger confined to one worker at a time, uses languageConstraints or languageHints because messages are short, tags entities with the .nameType scheme and scores mood with .sentimentScore, passes .omitWhitespace, .omitPunctuation and .joinNames, handles optional tags and sentiment without force unwraps, and checks that a word embedding exists before using it.",
|
|
9
9
|
"files": [],
|
|
10
10
|
"expectations": [
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"Uses
|
|
14
|
-
"
|
|
15
|
-
"
|
|
11
|
+
"Chooses appropriate tokenizer units and confines each tokenizer or tagger to a single thread",
|
|
12
|
+
"Adds languageConstraints or languageHints for short messages",
|
|
13
|
+
"Uses .nameType for entities and .sentimentScore for mood",
|
|
14
|
+
"Uses the options .omitWhitespace, .omitPunctuation and .joinNames",
|
|
15
|
+
"Handles optional tags, sentiment and embeddings without force unwrapping"
|
|
16
16
|
]
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
19
|
"id": 1,
|
|
20
20
|
"name": "translation-availability-review",
|
|
21
|
-
"prompt": "Review
|
|
22
|
-
"expected_output": "
|
|
21
|
+
"prompt": "Review our plan: we target iOS 17.4, call TranslationSession directly on launch with the high-fidelity strategy because it uses the cloud, and translate our menu in one batch without any error handling. What is wrong?",
|
|
22
|
+
"expected_output": "Separates availability: the system translation sheet exists from iOS 17.4, whereas iOS 18 is the floor for sessions, the translationTask modifier, LanguageAvailability and batches, and strategies need 26.4. Corrects the claim that .highFidelity uses a server: translation runs on device, with .highFidelity preferring Apple Intelligence models and .lowLatency the classic models. Uses LanguageAvailability with its installed, supported and unsupported states, puts every translate, translations(from:) and prepareTranslation call inside do-catch, and explains that TranslationSession(installedSource:target:) needs both languages installed while translationTask can prompt for downloads.",
|
|
23
23
|
"files": [],
|
|
24
24
|
"expectations": [
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"Explains that
|
|
25
|
+
"Distinguishes the 17.4 presentation API from the iOS 18 session, task, availability and batch APIs",
|
|
26
|
+
"States that neither strategy sends text to a server",
|
|
27
|
+
"Lists the .installed, .supported and .unsupported availability states",
|
|
28
|
+
"Catches errors from translate, translations(from:) and prepareTranslation",
|
|
29
|
+
"Explains that the installedSource initializer requires installed languages whereas translationTask can request downloads"
|
|
30
30
|
]
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
33
|
"id": 2,
|
|
34
34
|
"name": "sibling-boundary-routing",
|
|
35
|
-
"prompt": "
|
|
36
|
-
"expected_output": "
|
|
35
|
+
"prompt": "Our travel journal app scans printed tickets, dictates voice notes, shows its UI in eight languages, summarizes each trip, and tags places and moods in the journal text. Which parts belong to the NaturalLanguage skill and which go elsewhere?",
|
|
36
|
+
"expected_output": "Keeps tokenization, language identification, entity extraction, sentiment, embeddings and translation of journal text in this skill. Ticket OCR goes to vision-framework, voice-note transcription to speech-recognition, String Catalogs, plurals and formatting to ios-localization, and generated trip summaries to apple-on-device-ai.",
|
|
37
37
|
"files": [],
|
|
38
38
|
"expectations": [
|
|
39
|
-
"Keeps tokenization, language identification,
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
39
|
+
"Keeps tokenization, language identification, entities, sentiment, embeddings and translation here",
|
|
40
|
+
"Sends ticket OCR to vision-framework",
|
|
41
|
+
"Sends voice-note transcription to speech-recognition",
|
|
42
|
+
"Sends UI strings, plurals and formatting to ios-localization",
|
|
43
|
+
"Sends generated trip summaries to apple-on-device-ai"
|
|
44
44
|
]
|
|
45
45
|
}
|
|
46
46
|
]
|
|
@@ -1,324 +1,270 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Translation and text-analysis patterns
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
that exceed the main skill file's scope.
|
|
3
|
+
Deeper material for the `natural-language` skill ([../SKILL.md](../SKILL.md)).
|
|
5
4
|
|
|
6
|
-
##
|
|
5
|
+
## Plugging in a Create ML model
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
- [NLTagger with Multiple Schemes](#nltagger-with-multiple-schemes)
|
|
12
|
-
- [Translation with Replacement Action](#translation-with-replacement-action)
|
|
13
|
-
- [Translation Session Strategies](#translation-session-strategies)
|
|
14
|
-
- [SwiftUI Integration Patterns](#swiftui-integration-patterns)
|
|
15
|
-
- [Lemmatization](#lemmatization)
|
|
16
|
-
|
|
17
|
-
## Custom NLModel Integration
|
|
18
|
-
|
|
19
|
-
Load a Create ML text classifier or word tagger into `NLTagger` via `NLModel`.
|
|
7
|
+
A text classifier or word tagger trained in Create ML is loaded as an
|
|
8
|
+
`MLModel`, wrapped in `NLModel`, and then either attached to a tagger or
|
|
9
|
+
called directly.
|
|
20
10
|
|
|
21
11
|
```swift
|
|
22
|
-
import NaturalLanguage
|
|
23
12
|
import CoreML
|
|
13
|
+
import NaturalLanguage
|
|
24
14
|
|
|
25
|
-
func
|
|
26
|
-
let
|
|
27
|
-
let
|
|
28
|
-
|
|
29
|
-
let tagger = NLTagger(tagSchemes: [
|
|
30
|
-
tagger.setModels([
|
|
31
|
-
return tagger
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Direct prediction without a tagger
|
|
35
|
-
func classifyText(_ text: String) throws -> String? {
|
|
36
|
-
let mlModel = try MLModel(contentsOf: modelURL)
|
|
37
|
-
let nlModel = try NLModel(mlModel: mlModel)
|
|
38
|
-
return nlModel.predictedLabel(for: text)
|
|
15
|
+
func makeTicketTagger(modelURL: URL) throws -> (NLTagger, NLModel) {
|
|
16
|
+
let compiled = try MLModel(contentsOf: modelURL)
|
|
17
|
+
let wrapper = try NLModel(mlModel: compiled)
|
|
18
|
+
let routing = NLTagScheme("TicketRouting")
|
|
19
|
+
let tagger = NLTagger(tagSchemes: [routing])
|
|
20
|
+
tagger.setModels([wrapper], forTagScheme: routing)
|
|
21
|
+
return (tagger, wrapper)
|
|
39
22
|
}
|
|
40
23
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
let
|
|
44
|
-
|
|
45
|
-
return nlModel.predictedLabelHypotheses(for: text, maximumCount: 5)
|
|
24
|
+
func triage(_ ticket: String, with wrapper: NLModel) -> (String?, [String: Double]) {
|
|
25
|
+
let top = wrapper.predictedLabel(for: ticket)
|
|
26
|
+
let spread = wrapper.predictedLabelHypotheses(for: ticket, maximumCount: 3)
|
|
27
|
+
return (top, spread)
|
|
46
28
|
}
|
|
47
29
|
```
|
|
48
30
|
|
|
49
|
-
## Contextual
|
|
31
|
+
## Contextual embeddings
|
|
50
32
|
|
|
51
|
-
`NLContextualEmbedding` produces
|
|
52
|
-
|
|
33
|
+
`NLContextualEmbedding` produces vectors that depend on the surrounding
|
|
34
|
+
words, so "bank" in "river bank" and "bank loan" get different values. The
|
|
35
|
+
initializer is failable, and the model assets may need a download first.
|
|
53
36
|
|
|
54
37
|
```swift
|
|
55
|
-
|
|
38
|
+
func tokenVectors(for text: String) async throws -> [[Double]] {
|
|
39
|
+
guard let model = NLContextualEmbedding(language: .english) else { return [] }
|
|
56
40
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return []
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Check and load assets
|
|
63
|
-
guard embedding.hasAvailableAssets else {
|
|
64
|
-
embedding.requestAssets { result, error in
|
|
65
|
-
// Handle download
|
|
66
|
-
}
|
|
67
|
-
return []
|
|
41
|
+
if !model.hasAvailableAssets {
|
|
42
|
+
let outcome = try await model.requestAssets()
|
|
43
|
+
guard outcome == .available else { return [] }
|
|
68
44
|
}
|
|
69
45
|
|
|
70
|
-
try
|
|
71
|
-
defer {
|
|
46
|
+
try model.load()
|
|
47
|
+
defer { model.unload() }
|
|
72
48
|
|
|
73
|
-
let result = try
|
|
74
|
-
var vectors: [
|
|
75
|
-
|
|
76
|
-
result.enumerateTokenVectors(in:
|
|
77
|
-
vectors.append(
|
|
49
|
+
let result = try model.embeddingResult(for: text, language: .english)
|
|
50
|
+
var vectors: [[Double]] = []
|
|
51
|
+
let whole = text.startIndex..<text.endIndex
|
|
52
|
+
result.enumerateTokenVectors(in: whole) { vector, _ in
|
|
53
|
+
vectors.append(vector)
|
|
78
54
|
return true
|
|
79
55
|
}
|
|
80
56
|
return vectors
|
|
81
57
|
}
|
|
82
58
|
```
|
|
83
59
|
|
|
84
|
-
|
|
60
|
+
A completion-handler form, `requestAssets { result, error in }`, is also
|
|
61
|
+
available. To see which models exist for a language:
|
|
85
62
|
|
|
86
63
|
```swift
|
|
87
|
-
let
|
|
88
|
-
.languages: [NLLanguage.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
print("Model: \(embedding.modelIdentifier)")
|
|
93
|
-
print("Dimension: \(embedding.dimension)")
|
|
94
|
-
print("Max length: \(embedding.maximumSequenceLength)")
|
|
64
|
+
let candidates = NLContextualEmbedding.contextualEmbeddings(
|
|
65
|
+
forValues: [.languages: [NLLanguage.german.rawValue]]
|
|
66
|
+
)
|
|
67
|
+
for model in candidates {
|
|
68
|
+
print(model.modelIdentifier, model.dimension, model.maximumSequenceLength)
|
|
95
69
|
}
|
|
96
70
|
```
|
|
97
71
|
|
|
98
|
-
## Gazetteers for
|
|
72
|
+
## Gazetteers for your own vocabulary
|
|
99
73
|
|
|
100
|
-
|
|
74
|
+
A gazetteer maps known terms to labels and overrides or supplements what the
|
|
75
|
+
tagger would say. Useful for product names, internal teams or medical terms.
|
|
101
76
|
|
|
102
77
|
```swift
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
"
|
|
106
|
-
"
|
|
107
|
-
]
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return tagger
|
|
113
|
-
}
|
|
78
|
+
let catalogue = try NLGazetteer(
|
|
79
|
+
dictionary: [
|
|
80
|
+
"Product": ["Aurora Hub", "Nimbus Cam"],
|
|
81
|
+
"Team": ["Platform Guild", "Night Shift"]
|
|
82
|
+
],
|
|
83
|
+
language: .english
|
|
84
|
+
)
|
|
85
|
+
let tagger = NLTagger(tagSchemes: [.nameType])
|
|
86
|
+
tagger.setGazetteers([catalogue], for: .nameType)
|
|
114
87
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
88
|
+
try NLGazetteer.write(["Product": ["Aurora Hub"]],
|
|
89
|
+
language: .english,
|
|
90
|
+
to: cacheFolder.appendingPathComponent("products.gazetteer"))
|
|
119
91
|
```
|
|
120
92
|
|
|
121
|
-
##
|
|
93
|
+
## One tagger, several schemes
|
|
122
94
|
|
|
123
|
-
|
|
95
|
+
Load all the schemes you need up front and query them from the same pass.
|
|
124
96
|
|
|
125
97
|
```swift
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
let word = String(text[tokenRange])
|
|
136
|
-
let (lemmaTag, _) = tagger.tag(at: tokenRange.lowerBound,
|
|
137
|
-
unit: .word, scheme: .lemma)
|
|
138
|
-
let lemma = lemmaTag?.rawValue ?? word
|
|
139
|
-
print("\(word) -> tag: \(tag?.rawValue ?? "?"), lemma: \(lemma)")
|
|
140
|
-
return true
|
|
141
|
-
}
|
|
98
|
+
let multi = NLTagger(tagSchemes: [.lexicalClass, .nameType, .lemma])
|
|
99
|
+
multi.string = note
|
|
100
|
+
multi.enumerateTags(in: note.startIndex..<note.endIndex,
|
|
101
|
+
unit: .word,
|
|
102
|
+
scheme: .nameTypeOrLexicalClass,
|
|
103
|
+
options: [.omitPunctuation, .omitWhitespace, .joinNames]) { kind, span in
|
|
104
|
+
let (root, _) = multi.tag(at: span.lowerBound, unit: .word, scheme: .lemma)
|
|
105
|
+
rows.append((String(note[span]), kind?.rawValue ?? "?", root?.rawValue))
|
|
106
|
+
return true
|
|
142
107
|
}
|
|
143
108
|
```
|
|
144
109
|
|
|
145
|
-
##
|
|
110
|
+
## Translating text in place
|
|
146
111
|
|
|
147
|
-
|
|
112
|
+
With a `replacementAction`, the system sheet offers a Replace button that
|
|
113
|
+
hands you the translated string.
|
|
148
114
|
|
|
149
115
|
```swift
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
struct EditableTranslationView: View {
|
|
154
|
-
@State private var text = "Hello, how are you?"
|
|
155
|
-
@State private var showTranslation = false
|
|
116
|
+
struct DraftEditor: View {
|
|
117
|
+
@State private var draft = ""
|
|
118
|
+
@State private var translating = false
|
|
156
119
|
|
|
157
120
|
var body: some View {
|
|
158
|
-
TextEditor(text: $
|
|
159
|
-
.toolbar {
|
|
160
|
-
|
|
121
|
+
TextEditor(text: $draft)
|
|
122
|
+
.toolbar { Button("Translate") { translating = true } }
|
|
123
|
+
.translationPresentation(isPresented: $translating, text: draft) { translated in
|
|
124
|
+
draft = translated
|
|
161
125
|
}
|
|
162
|
-
.translationPresentation(
|
|
163
|
-
isPresented: $showTranslation,
|
|
164
|
-
text: text,
|
|
165
|
-
replacementAction: { translated in
|
|
166
|
-
text = translated
|
|
167
|
-
}
|
|
168
|
-
)
|
|
169
126
|
}
|
|
170
127
|
}
|
|
171
128
|
```
|
|
172
129
|
|
|
173
|
-
##
|
|
130
|
+
## Choosing a translation strategy
|
|
174
131
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
`.
|
|
178
|
-
|
|
132
|
+
Requires iOS 26.4 or macOS 26.4. Translation always runs on the device.
|
|
133
|
+
`.highFidelity` prefers the Apple Intelligence translation models when the
|
|
134
|
+
device has them; `.lowLatency` uses the classic translation models. Neither
|
|
135
|
+
sends text to a server.
|
|
179
136
|
|
|
180
137
|
```swift
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
)
|
|
189
|
-
|
|
190
|
-
// Low latency: faster traditional translation models
|
|
191
|
-
let fastConfig = TranslationSession.Configuration(
|
|
192
|
-
source: Locale.Language(identifier: "en"),
|
|
193
|
-
target: Locale.Language(identifier: "ja"),
|
|
194
|
-
preferredStrategy: .lowLatency
|
|
195
|
-
)
|
|
138
|
+
if #available(iOS 26.4, macOS 26.4, *) {
|
|
139
|
+
request = TranslationSession.Configuration(
|
|
140
|
+
source: Locale.Language(identifier: "fr"),
|
|
141
|
+
target: Locale.Language(identifier: "en"),
|
|
142
|
+
preferredStrategy: .lowLatency
|
|
143
|
+
)
|
|
144
|
+
}
|
|
196
145
|
```
|
|
197
146
|
|
|
198
|
-
|
|
147
|
+
## Getting a session ready
|
|
199
148
|
|
|
200
|
-
|
|
149
|
+
Download models before the user is waiting on a result:
|
|
201
150
|
|
|
202
151
|
```swift
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
152
|
+
struct PhrasebookScreen: View {
|
|
153
|
+
@State private var warmUp: TranslationSession.Configuration?
|
|
154
|
+
|
|
155
|
+
var body: some View {
|
|
156
|
+
PhraseList()
|
|
157
|
+
.onAppear { warmUp = .init(source: .init(identifier: "es"), target: .init(identifier: "en")) }
|
|
158
|
+
.translationTask(warmUp) { @concurrent session in
|
|
159
|
+
do {
|
|
160
|
+
try await session.prepareTranslation() // triggers any download now
|
|
161
|
+
} catch {
|
|
162
|
+
// declined download, cancellation, or an unsupported pair
|
|
163
|
+
}
|
|
164
|
+
}
|
|
213
165
|
}
|
|
214
166
|
}
|
|
215
167
|
```
|
|
216
168
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
169
|
+
`PhraseList` stands for the app's own content view. The closure is
|
|
170
|
+
`@concurrent` for the same reason as in the main skill: the session is not
|
|
171
|
+
`Sendable` and cannot be used from the main actor.
|
|
172
|
+
|
|
173
|
+
`TranslationSession(installedSource:target:)` (iOS 26, macOS 26) builds a
|
|
174
|
+
session without any view. The initializer does not throw; the session works
|
|
175
|
+
only with models already on the device, so translating fails when either
|
|
176
|
+
language is missing. Create it only after `LanguageAvailability` reports
|
|
177
|
+
`.installed`; a `.translationTask` session, in contrast, can ask the user to
|
|
178
|
+
download.
|
|
220
179
|
|
|
221
|
-
|
|
180
|
+
```swift
|
|
181
|
+
@available(iOS 26, macOS 26, *)
|
|
182
|
+
func quietSession(from source: Locale.Language, to target: Locale.Language) async -> TranslationSession? {
|
|
183
|
+
let state = await LanguageAvailability().status(from: source, to: target)
|
|
184
|
+
guard state == .installed else { return nil }
|
|
185
|
+
return TranslationSession(installedSource: source, target: target)
|
|
186
|
+
}
|
|
187
|
+
```
|
|
222
188
|
|
|
223
|
-
|
|
189
|
+
## A live analysis panel in SwiftUI
|
|
224
190
|
|
|
225
191
|
```swift
|
|
226
|
-
import SwiftUI
|
|
227
192
|
import NaturalLanguage
|
|
193
|
+
import Observation
|
|
194
|
+
import SwiftUI
|
|
228
195
|
|
|
229
196
|
@Observable
|
|
230
197
|
@MainActor
|
|
231
|
-
final class
|
|
232
|
-
var
|
|
233
|
-
var
|
|
234
|
-
var
|
|
235
|
-
|
|
236
|
-
func
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
// Sentiment
|
|
250
|
-
let tagger = NLTagger(tagSchemes: [.sentimentScore])
|
|
251
|
-
tagger.string = text
|
|
252
|
-
let (tag, _) = tagger.tag(at: text.startIndex, unit: .paragraph,
|
|
253
|
-
scheme: .sentimentScore)
|
|
254
|
-
if let score = tag.flatMap({ Double($0.rawValue) }) {
|
|
255
|
-
sentimentLabel = score > 0.1 ? "Positive" :
|
|
256
|
-
score < -0.1 ? "Negative" : "Neutral"
|
|
257
|
-
}
|
|
198
|
+
final class TextInsights {
|
|
199
|
+
private(set) var wordCount = 0
|
|
200
|
+
private(set) var languageCode = "-"
|
|
201
|
+
private(set) var tone = "neutral"
|
|
202
|
+
|
|
203
|
+
func update(for text: String) {
|
|
204
|
+
let words = NLTokenizer(unit: .word)
|
|
205
|
+
words.string = text
|
|
206
|
+
let everything = text.startIndex..<text.endIndex
|
|
207
|
+
wordCount = words.tokens(for: everything).count
|
|
208
|
+
|
|
209
|
+
languageCode = NLLanguageRecognizer.dominantLanguage(for: text)?.rawValue ?? "-"
|
|
210
|
+
|
|
211
|
+
let scorer = NLTagger(tagSchemes: [.sentimentScore])
|
|
212
|
+
scorer.string = text
|
|
213
|
+
let (moodTag, _) = scorer.tag(at: everything.lowerBound, unit: .paragraph, scheme: .sentimentScore)
|
|
214
|
+
let value = moodTag.flatMap { Double($0.rawValue) } ?? 0
|
|
215
|
+
tone = value > 0.1 ? "positive" : value < -0.1 ? "negative" : "neutral"
|
|
258
216
|
}
|
|
259
217
|
}
|
|
260
218
|
|
|
261
|
-
struct
|
|
262
|
-
@State private var
|
|
263
|
-
@State private var
|
|
219
|
+
struct InsightsPanel: View {
|
|
220
|
+
@State private var input = ""
|
|
221
|
+
@State private var insights = TextInsights()
|
|
264
222
|
|
|
265
223
|
var body: some View {
|
|
266
224
|
Form {
|
|
267
|
-
TextField("
|
|
268
|
-
.onChange(of:
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
LabeledContent("Language", value: analyzer.detectedLanguage)
|
|
273
|
-
LabeledContent("Sentiment", value: analyzer.sentimentLabel)
|
|
274
|
-
LabeledContent("Words", value: "\(analyzer.tokens.count)")
|
|
275
|
-
}
|
|
225
|
+
TextField("Type something", text: $input, axis: .vertical)
|
|
226
|
+
.onChange(of: input) { _, text in insights.update(for: text) }
|
|
227
|
+
LabeledContent("Words", value: "\(insights.wordCount)")
|
|
228
|
+
LabeledContent("Language", value: insights.languageCode)
|
|
229
|
+
LabeledContent("Tone", value: insights.tone)
|
|
276
230
|
}
|
|
277
231
|
}
|
|
278
232
|
}
|
|
279
233
|
```
|
|
280
234
|
|
|
281
|
-
###
|
|
235
|
+
### Tagger assets
|
|
282
236
|
|
|
283
|
-
Some
|
|
237
|
+
Some schemes need assets that are fetched on demand:
|
|
284
238
|
|
|
285
239
|
```swift
|
|
286
|
-
NLTagger.requestAssets(for: .
|
|
287
|
-
switch
|
|
288
|
-
case .available:
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
// Assets not available for this language/scheme
|
|
293
|
-
break
|
|
294
|
-
case .error:
|
|
295
|
-
print("Asset request error: \(error?.localizedDescription ?? "")")
|
|
296
|
-
@unknown default:
|
|
297
|
-
break
|
|
240
|
+
NLTagger.requestAssets(for: .korean, tagScheme: .lexicalClass) { outcome, _ in
|
|
241
|
+
switch outcome {
|
|
242
|
+
case .available: break // ready to tag
|
|
243
|
+
case .notAvailable: break // this scheme is not offered for the language
|
|
244
|
+
case .error: break // retry later
|
|
245
|
+
@unknown default: break
|
|
298
246
|
}
|
|
299
247
|
}
|
|
300
248
|
```
|
|
301
249
|
|
|
302
|
-
##
|
|
250
|
+
## Lemmas for search
|
|
303
251
|
|
|
304
|
-
|
|
252
|
+
Reducing words to their dictionary form makes "running" and "ran" match
|
|
253
|
+
"run", and "were" match "be". Handy for indexing and search keys.
|
|
305
254
|
|
|
306
255
|
```swift
|
|
307
|
-
func
|
|
256
|
+
func lemmas(in text: String) -> [String] {
|
|
308
257
|
let tagger = NLTagger(tagSchemes: [.lemma])
|
|
309
258
|
tagger.string = text
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
tagger.enumerateTags(
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
) { tag, range in
|
|
318
|
-
lemmas.append(tag?.rawValue ?? String(text[range]))
|
|
259
|
+
var roots: [String] = []
|
|
260
|
+
let fullRange = text.startIndex..<text.endIndex
|
|
261
|
+
tagger.enumerateTags(in: fullRange,
|
|
262
|
+
unit: .word,
|
|
263
|
+
scheme: .lemma,
|
|
264
|
+
options: [.omitPunctuation, .omitWhitespace]) { tag, span in
|
|
265
|
+
roots.append(tag?.rawValue ?? String(text[span]))
|
|
319
266
|
return true
|
|
320
267
|
}
|
|
321
|
-
return
|
|
268
|
+
return roots
|
|
322
269
|
}
|
|
323
|
-
// "The cats were running quickly" -> ["the", "cat", "be", "run", "quickly"]
|
|
324
270
|
```
|