@salesforce/afv-skills 1.59.0 → 1.60.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.
Files changed (173) hide show
  1. package/package.json +1 -1
  2. package/skills/agentforce-architecture-analyze/SKILL.md +66 -17
  3. package/skills/agentforce-architecture-analyze/assets/cli/show_access_token.yaml +4 -7
  4. package/skills/agentforce-architecture-analyze/references/contract.json +1 -1
  5. package/skills/agentforce-architecture-analyze/scripts/emit_env.py +2 -2
  6. package/skills/agentforce-architecture-analyze/scripts/main.py +40 -44
  7. package/skills/agentforce-architecture-analyze/scripts/rest_client.py +11 -3
  8. package/skills/agentforce-architecture-analyze/scripts/sf_cli.py +77 -10
  9. package/skills/agentforce-architecture-analyze/scripts/tests/test_end_to_end_fixture.py +1 -0
  10. package/skills/agentforce-architecture-analyze/scripts/tests/test_flow_children_inflation.py +1 -0
  11. package/skills/agentforce-architecture-analyze/scripts/tests/test_main_pipeline.py +53 -2
  12. package/skills/agentforce-architecture-analyze/scripts/tests/test_resolve_creds.py +184 -36
  13. package/skills/agentforce-architecture-analyze/scripts/tests/test_rest_client.py +17 -0
  14. package/skills/agentforce-architecture-analyze/scripts/tests/test_sf_cli.py +165 -11
  15. package/skills/agentforce-architecture-analyze/scripts/tests/test_skill_md_pipeline_block.py +319 -0
  16. package/skills/agentforce-d360-analyze/SKILL.md +28 -10
  17. package/skills/agentforce-d360-analyze/scripts/dc.py +200 -50
  18. package/skills/agentforce-d360-analyze/scripts/discover_sessions.py +10 -6
  19. package/skills/agentforce-d360-analyze/scripts/fetch_dc.py +22 -6
  20. package/skills/agentforce-d360-analyze/scripts/resolve_session.py +21 -13
  21. package/skills/agentforce-d360-analyze/scripts/tests/test_dc_and_resolve_session.py +298 -76
  22. package/skills/agentforce-d360-analyze/scripts/tests/test_default_target_org.py +432 -0
  23. package/skills/agentforce-d360-analyze/scripts/tests/test_discover_sessions.py +1 -1
  24. package/skills/agentforce-d360-analyze/scripts/tests/test_resolve_session_main.py +9 -3
  25. package/skills/agentforce-d360-analyze/scripts/tests/test_skill_md_prefix_block.py +176 -0
  26. package/skills/consumer-goods-accruals-datakit-deploy/SKILL.md +17 -27
  27. package/skills/consumer-goods-accruals-datakit-deploy/scripts/setup.js +7 -17
  28. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/00-check-prerequisites.js +47 -63
  29. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/01-download-static-resource.js +10 -13
  30. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/02-replace-org-id.js +46 -46
  31. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/03-deploy-metadata.js +4 -21
  32. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/06-create-dataspace.js +58 -82
  33. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/07-deploy-accruals-reports.js +16 -315
  34. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/08-deploy-ui.js +9 -24
  35. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/09-completion.js +44 -44
  36. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/utils.js +11 -63
  37. package/skills/consumer-goods-rtr-datacloud-export-configure/SKILL.md +2 -1
  38. package/skills/consumer-goods-tpe-dashboard-configure/SKILL.md +2 -1
  39. package/skills/consumer-goods-tpe-dashboard-custom-kpi-configure/SKILL.md +2 -1
  40. package/skills/consumer-goods-tpe-datakit-deploy/SKILL.md +2 -1
  41. package/skills/data360-schema-get/SKILL.md +3 -3
  42. package/skills/design-systems-slds-validate/references/report-format.md +1 -1
  43. package/skills/dx-org-manage/SKILL.md +1 -0
  44. package/skills/dx-org-shape-manage/SKILL.md +1 -0
  45. package/skills/dx-org-snapshot-manage/SKILL.md +172 -0
  46. package/skills/dx-org-snapshot-manage/examples/create_error_output.json +16 -0
  47. package/skills/dx-org-snapshot-manage/examples/create_success_output.json +19 -0
  48. package/skills/dx-org-snapshot-manage/examples/delete_output.json +9 -0
  49. package/skills/dx-org-snapshot-manage/examples/get_output.json +19 -0
  50. package/skills/dx-org-snapshot-manage/examples/list_output.json +36 -0
  51. package/skills/dx-org-snapshot-manage/references/cli_flags.md +179 -0
  52. package/skills/dx-org-snapshot-manage/references/snapshot_usage.md +55 -0
  53. package/skills/dx-org-trial-expiration-check/SKILL.md +1 -1
  54. package/skills/dx-org-trial-expiration-check/scripts/check_expiration.sh +2 -2
  55. package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +7 -5
  56. package/skills/education-cloud-student-recruitment-agent-configure/references/prerequisites.md +11 -11
  57. package/skills/experience-content-media-image-generate/SKILL.md +83 -0
  58. package/skills/experience-content-media-image-generate/scripts/download-image.sh +84 -0
  59. package/skills/external-diagram-mermaid-generate/SKILL.md +12 -12
  60. package/skills/field-service-data-capture-migrate/references/component-mapping.md +1 -1
  61. package/skills/field-service-data-capture-migrate/references/fsm-dc-capability-catalog.md +1 -2
  62. package/skills/field-service-data-capture-migrate/references/known-deploy-errors.md +1 -0
  63. package/skills/field-service-data-capture-migrate/references/transformer-rules.md +1 -1
  64. package/skills/field-service-data-capture-migrate/scripts/transform_flow.py +12 -1
  65. package/skills/field-service-data-capture-migrate/scripts/vendor/build_flow.py +4 -1
  66. package/skills/field-service-setup-orchestrator-get/SKILL.md +0 -1
  67. package/skills/insurance-brokerage-agency-billing-configure/SKILL.md +233 -0
  68. package/skills/insurance-brokerage-agency-billing-configure/references/accounting-setup.md +117 -0
  69. package/skills/insurance-brokerage-agency-billing-configure/references/billing-rules-config.md +237 -0
  70. package/skills/insurance-brokerage-agency-billing-configure/references/billing-settings.md +271 -0
  71. package/skills/insurance-brokerage-agency-billing-configure/references/demo-policy-config.md +138 -0
  72. package/skills/insurance-brokerage-agency-billing-configure/references/org-defaults.md +64 -0
  73. package/skills/insurance-brokerage-agency-billing-configure/references/permissions-config.md +226 -0
  74. package/skills/insurance-brokerage-agency-billing-configure/references/prerequisites.md +142 -0
  75. package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +3 -2
  76. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-execution-state-and-recovery.md +3 -3
  77. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-overview.md +68 -45
  78. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-visit-creation-data.md +17 -18
  79. package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +16 -3
  80. package/skills/life-sciences-kam-coordinate/references/stage-5-data-creation-data.md +16 -13
  81. package/skills/marketing-message-test/SKILL.md +194 -0
  82. package/skills/marketing-message-test/references/api-contract.md +333 -0
  83. package/skills/omnistudio-callable-apex-generate/SKILL.md +3 -3
  84. package/skills/omnistudio-datamapper-generate/SKILL.md +6 -6
  85. package/skills/omnistudio-datapacks-deploy/SKILL.md +11 -11
  86. package/skills/omnistudio-dependencies-analyze/SKILL.md +5 -5
  87. package/skills/omnistudio-epc-catalog-generate/SKILL.md +6 -6
  88. package/skills/omnistudio-flexcard-generate/SKILL.md +6 -6
  89. package/skills/omnistudio-integration-procedure-generate/SKILL.md +6 -6
  90. package/skills/omnistudio-omniscript-generate/SKILL.md +6 -5
  91. package/skills/platform-apex-logs-debug/SKILL.md +1 -0
  92. package/skills/platform-metadata-deploy/SKILL.md +1 -0
  93. package/skills/platform-models-api-configure/SKILL.md +5 -5
  94. package/skills/platform-soql-query/SKILL.md +1 -0
  95. package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +17 -6
  96. package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +107 -192
  97. package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone-action.json +6 -6
  98. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +49 -20
  99. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +4 -4
  100. package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +224 -290
  101. package/skills/service-itsm-agentic-setup-incident-sla-configure/references/workflow.md +295 -0
  102. package/skills/service-itsm-incident-priority-configure/SKILL.md +1 -1
  103. package/skills/service-itsm-slack-itservice-configure/SKILL.md +2 -1
  104. package/skills/service-itsm-slack-itservice-configure/references/manage-slack-connection.md +2 -2
  105. package/skills/service-omni-channel-setup-coordinate/SKILL.md +20 -13
  106. package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +5 -55
  107. package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +0 -38
  108. package/skills/service-omni-command-center-analyze/SKILL.md +2 -3
  109. package/skills/service-omni-command-center-analyze/scripts/analyze.sh +3 -3
  110. package/skills/tableau-next-asset-create/README.md +65 -0
  111. package/skills/tableau-next-asset-create/SKILL.md +409 -0
  112. package/skills/tableau-next-asset-create/references/admin-users.md +149 -0
  113. package/skills/tableau-next-asset-create/references/ai-readiness.md +355 -0
  114. package/skills/tableau-next-asset-create/references/alerts.md +111 -0
  115. package/skills/tableau-next-asset-create/references/build-workflow.md +819 -0
  116. package/skills/tableau-next-asset-create/references/dashboard-authoring.md +302 -0
  117. package/skills/tableau-next-asset-create/references/dashboard-design-principles.md +352 -0
  118. package/skills/tableau-next-asset-create/references/data-transform-gotchas.md +210 -0
  119. package/skills/tableau-next-asset-create/references/data-understanding.md +387 -0
  120. package/skills/tableau-next-asset-create/references/deep-reference-index.md +74 -0
  121. package/skills/tableau-next-asset-create/references/destructive-operations.md +62 -0
  122. package/skills/tableau-next-asset-create/references/edit-dashboard.md +273 -0
  123. package/skills/tableau-next-asset-create/references/edit-visualization.md +529 -0
  124. package/skills/tableau-next-asset-create/references/empty-source-handling.md +104 -0
  125. package/skills/tableau-next-asset-create/references/ingest-and-metric-gotchas.md +638 -0
  126. package/skills/tableau-next-asset-create/references/insight-bundle.md +69 -0
  127. package/skills/tableau-next-asset-create/references/large-flat-file-handling.md +331 -0
  128. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/_envelope.json +54 -0
  129. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/_shared-widget-fields.json +122 -0
  130. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/add_page.json +29 -0
  131. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/delete_page.json +27 -0
  132. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/discard_dashboard.json +11 -0
  133. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/move_widget.json +30 -0
  134. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/move_widget_to_page.json +30 -0
  135. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/place_widget_on_page.json +30 -0
  136. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/remove_widget_from_dashboard.json +16 -0
  137. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/remove_widget_from_page.json +26 -0
  138. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/rename_page.json +28 -0
  139. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/save_dashboard.json +18 -0
  140. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/undo.json +11 -0
  141. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_button_widget.json +69 -0
  142. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_container_widget.json +88 -0
  143. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_filter_widget.json +146 -0
  144. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_metric_widget.json +78 -0
  145. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_navigation_widget.json +80 -0
  146. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_parameter_widget.json +160 -0
  147. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_text_widget.json +103 -0
  148. package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_visualization_widget.json +68 -0
  149. package/skills/tableau-next-asset-create/references/sdm-tool-reference.md +721 -0
  150. package/skills/tableau-next-asset-create/references/semantic-query-and-enrichment.md +355 -0
  151. package/skills/tableau-next-asset-create/references/shared-gates.md +322 -0
  152. package/skills/tableau-next-asset-create/references/sharing-and-promotion.md +306 -0
  153. package/skills/tableau-next-asset-create/references/tasks/ai-readiness-audit.md +51 -0
  154. package/skills/tableau-next-asset-create/references/tasks/analyze-data.md +48 -0
  155. package/skills/tableau-next-asset-create/references/tasks/build-dashboard.md +66 -0
  156. package/skills/tableau-next-asset-create/references/tasks/build-end-to-end.md +73 -0
  157. package/skills/tableau-next-asset-create/references/tasks/create-data-transform.md +51 -0
  158. package/skills/tableau-next-asset-create/references/tasks/create-viz.md +58 -0
  159. package/skills/tableau-next-asset-create/references/tasks/edit-dashboard.md +80 -0
  160. package/skills/tableau-next-asset-create/references/tasks/edit-sdm.md +106 -0
  161. package/skills/tableau-next-asset-create/references/tasks/edit-viz.md +40 -0
  162. package/skills/tableau-next-asset-create/references/tasks/enrich-model.md +68 -0
  163. package/skills/tableau-next-asset-create/references/tasks/ingest-flat-file.md +68 -0
  164. package/skills/tableau-next-asset-create/references/tasks/manage-alert.md +35 -0
  165. package/skills/tableau-next-asset-create/references/tasks/profile-dataset.md +47 -0
  166. package/skills/tableau-next-asset-create/references/tasks/promote-or-reuse.md +46 -0
  167. package/skills/tableau-next-asset-create/references/tasks/provision-user.md +39 -0
  168. package/skills/tableau-next-asset-create/references/tasks/query-model.md +92 -0
  169. package/skills/tableau-next-asset-create/references/tasks/review-verified-questions.md +42 -0
  170. package/skills/tableau-next-asset-create/references/tasks/share-asset.md +37 -0
  171. package/skills/tableau-next-asset-create/references/verified-questions.md +125 -0
  172. package/skills/tableau-next-asset-create/references/viz-authoring.md +992 -0
  173. package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/predefined-incident-policy.json +0 -102
@@ -0,0 +1,721 @@
1
+ # SDM Tool Reference
2
+
3
+ Input shapes and gotchas for the Tableau Next MCP semantic-model tools. Tool
4
+ names are shown bare; invoke each under your client's name for that
5
+ `tableau-next-*` server tool (see `shared-gates.md`).
6
+
7
+ ## Contents
8
+
9
+ Jump to the section that matches the current intent — do not apply the rest.
10
+
11
+ - `*__dll` / `*__dlm` / `*__dlc` rejected or missing → Source-name suffixes
12
+ - Invented / suffixed field apiName after auto-bind → The apiName-mutation gotcha
13
+ - Bind fields at create (one call, no N add_dimension) → create_semantic_model
14
+ - Join "field could not be found" / `leftFieldType` → add_semantic_model_relationship
15
+ - Cross-object query throws with no join path → queryUnrelatedDataObjects
16
+ - List DLOs / DMOs / models / dashboards → Discovering assets — browse_data_assets
17
+ - Create or extend an SDM / bulk-create timeout → create_semantic_model
18
+ - Measure agg vs `dataType` mismatch → add_semantic_model_measure
19
+ - Description-only or hidden-field update (`isVisible` echo) → Updates — sparse vs PUT
20
+ - Parameter PUT (`label`/`type`/`dataType`/`defaultValue`; `List` values) → Parameters
21
+ - HardJoin / Union / CustomSQL payloads → Logical views
22
+ - Component delete (calc / metric / object / LV / relationship) → Deleting a semantic definition
23
+ - `defaultExc` string vs flat object → Response double-wrap
24
+
25
+ ---
26
+
27
+ ## Source-name suffixes
28
+
29
+ `add_semantic_model_data_object.dataObjectName` requires a type suffix. Bare
30
+ names from `browse_data_assets` are rejected with "DMO/CI/DLO does not exist".
31
+
32
+ | Source type | `dataObjectType` | Suffix | Example |
33
+ |---|---|---|---|
34
+ | Data Lake Object | `Dlo` | `__dll` | `accounts__dll` |
35
+ | Data Model Object | `Dmo` | `__dlm` | `ssot__Account__dlm` |
36
+ | Calculated Insight | `Cio` | `__dlc` | `churn_score__dlc` |
37
+
38
+ If `__dlm` fails for a CSV-backed object that `browse_data_assets` labeled as a
39
+ DMO, retry once with `__dll` — the browse filter sometimes mislabels DLO-backed
40
+ CSV objects. This one-time suffix correction is distinct from a `run_query`
41
+ "table does not exist" error during the Step 2 row-count check: for an
42
+ *externally discovered* candidate that error means the object is unmaterialized
43
+ (0 fields) and must NOT be retried — exclude it. For a DMO you just created
44
+ and mapped in this same flow, the same error is NOT-READY — poll `run_query`
45
+ until the table exists (`COUNT = 0` is READY; `empty-source-handling.md`; G2).
46
+
47
+ The same `__dll` / `__dlm` / `__dlc` table names are what `run_query` selects
48
+ from for the Step 2 row-count checks.
49
+
50
+ ## The apiName-mutation gotcha (most common failure)
51
+
52
+ **Do not bind with `shouldIncludeAllFields: true`.** That flag is deprecated
53
+ and the server **numerically suffixes every
54
+ auto-bound dimension/measure apiName**, even on the first object with no name
55
+ collision:
56
+
57
+ - `Order_ID__c` → `Order_ID3`
58
+ - `Region__c` → `Region4`
59
+ - `account_id__c` → `account_id5`
60
+
61
+ It also sometimes rewrites `dataObjectFieldName` (`Id__c` → `Idc__c`). The
62
+ suffix is not predictable from the source name. The suffixed apiName is what
63
+ `list_semantic_model_dimensions` returns, and it is the value to pass to
64
+ `add_semantic_model_relationship`.
65
+
66
+ **Preferred bind:** fetch the DMO/DLO fields first, then pass explicit
67
+ `semanticDimensions[]` / `semanticMeasurements[]` **nested in
68
+ `create_semantic_model`** (or `add_semantic_model_data_object` for a later
69
+ object) with `shouldIncludeAllFields: false`. You control each field's
70
+ `apiName`, so `add_semantic_model_relationship` resolves first-try. Do **not**
71
+ follow create with N incremental `add_semantic_model_dimension` /
72
+ `add_semantic_model_measure` calls — that is the 27-call / 365s bind path.
73
+
74
+ HardJoin logical-view objects still use `shouldIncludeAllFields: true`
75
+ (apiNames are assigned at first save — see Logical views). If you ever inherit
76
+ a bulk-bound object, always call `list_semantic_model_dimensions` (and
77
+ `list_semantic_model_data_objects` for object apiNames) and copy the exact
78
+ stored apiName into the next call. Never construct the suffixed name yourself.
79
+
80
+ ## add_semantic_model_relationship — criteria field rules
81
+
82
+ The `criteria[].leftFieldType` / `rightFieldType` determines what apiName form
83
+ to use:
84
+
85
+ | fieldType | When | apiName to use |
86
+ |---|---|---|
87
+ | `TableField` | regular dimensions/measures (the common case) | the **semantic dimension apiName** from `list_semantic_model_dimensions` (e.g. `Account_Id5`) — NOT `dataObjectFieldName` |
88
+ | `SemanticField` | calculated dimensions only | the calculated dimension's apiName; must have a row-level dependency on the object (pure constants rejected; aggregations rejected with `SEMANTIC_FIELD_LEVEL_ERROR`) |
89
+ | `Formula` | expression-based joins | a TUA expression like `POWER([object].[field], 1)`; row-level only; left/right return types must match |
90
+
91
+ Using `dataObjectFieldName` with `TableField` returns "field could not be
92
+ found" even though the field exists — this is the single most common
93
+ relationship error.
94
+
95
+ Other relationship constraints:
96
+
97
+ - `joinType` MUST be `Auto` for model-level relationships. `Left` / `Right` /
98
+ `Inner` / `Full` are valid only inside a logical view (`logicalViewId` set).
99
+ - `label` is REQUIRED despite the schema marking it optional.
100
+ - `cardinality`: `OneToOne` / `OneToMany` / `ManyToOne` / `ManyToMany` /
101
+ `Unspecified`. A fact→dimension join is typically `ManyToOne`.
102
+ - `criteria` is usually a single `Equals` on the natural key.
103
+ - **Formula** left/right return types must match or the API returns
104
+ `CREATE_SEMANTIC_ENTITY_FAILED` with a message containing "must be of the
105
+ same type".
106
+
107
+ ## queryUnrelatedDataObjects
108
+
109
+ `list_semantic_models` returns `queryUnrelatedDataObjects` per model. When it
110
+ is `"Exception"`, a semantic query that spans two objects with no join path
111
+ **throws** rather than returning partial data. This is why an island object
112
+ breaks queries hard, not softly. Joining every object avoids it.
113
+
114
+ **`list_semantic_models`: an unknown `dataspace` returns a raw 500**, not an
115
+ empty list or a 400. Verify the dataspace exists before filtering on it.
116
+
117
+ ## Discovering assets — browse_data_assets
118
+
119
+ The single discovery endpoint across all asset types — DLOs/DMOs/CIOs, dashboards,
120
+ visualizations, workspaces, semantic models. Step 1 of the happy path below.
121
+
122
+ **Calling convention.** To list all assets of one type: `searchTerm: ""` (a literal
123
+ empty string — omitting it returns `UNKNOWN_EXCEPTION`) plus an `AssetType In [...]`
124
+ filter.
125
+
126
+ ```jsonc
127
+ // Literal "" — omit searchTerm → UNKNOWN_EXCEPTION. Repeat with
128
+ // MktDataModelObject / MktCalculatedInsightObject for DMOs / CIOs.
129
+ {
130
+ "searchTerm": "",
131
+ "filters": {
132
+ "filters": [
133
+ { "field": "AssetType", "operator": "In",
134
+ "values": ["MktDataLakeObject"] }
135
+ ]
136
+ },
137
+ "limit": 50
138
+ }
139
+ ```
140
+
141
+ **`AssetType` is case-sensitive and unvalidated — a typo returns zero results, not
142
+ an error.** Use the exact-cased values only: `AnalyticsDashboard`,
143
+ `AnalyticsVisualization`, `AnalyticsWorkspace`, `SemanticModel`,
144
+ `SemanticDefinition`, `MktDataLakeObject` (DLO), `MktDataModelObject` (DMO),
145
+ `MktCalculatedInsightObject` (CIO). A zero-result response for a plausible-looking
146
+ type name means "check the casing/spelling," not "no assets exist."
147
+
148
+ **Empty-`searchTerm` matrix.** `searchTerm: ""` works for `MktDataLakeObject` /
149
+ `MktDataModelObject` / `MktCalculatedInsightObject` but throws `UNKNOWN_EXCEPTION`
150
+ for `AnalyticsDashboard` / `AnalyticsVisualization` / `AnalyticsWorkspace` /
151
+ `SemanticModel` / `SemanticDefinition`. For those five, either use the per-type
152
+ list tool (`list_dashboards` / `list_visualizations` / `list_workspaces` /
153
+ `list_semantic_models`) or pass a real ≥2-character search term (1-char terms are
154
+ rejected with `search term must be longer than one character`).
155
+
156
+ **`And` behaves like `Or`.** `conjunctiveOperator: "And"` over multiple
157
+ `AssetType In` clauses returns the union, not an intersection — true intersection
158
+ isn't implemented (e.g. `AssetType In [SemanticModel] And AssetType In
159
+ [AnalyticsWorkspace]` returns the union, not the empty set). `conjunctiveOperator:
160
+ "Or"` over heterogeneous filter shapes also frequently returns `UNKNOWN_EXCEPTION`.
161
+ Compose at most one filter clause per call and intersect client-side if you need one.
162
+
163
+ **Only `AssetType` filters universally.** Type-specific fields (e.g. `CreatedBy`
164
+ on `SemanticModel`) return `Invalid filter field for type ...` — don't assume
165
+ per-type filter validity.
166
+
167
+ **Scope: current org only.**
168
+
169
+ Prefer the per-type tools (`list_visualizations`, `list_semantic_models`,
170
+ `list_workspace_assets`) when you need their richer per-type detail (dataSource,
171
+ chaining URLs, workspace scoping) rather than the generic `assets[]` shape.
172
+
173
+ **`list_workspaces` has no pagination metadata and an undocumented oldest-first
174
+ sort** (ascending by `createdDate`, no `total`/`hasNextPage`/page URL). To find
175
+ the *most recently created* workspace, don't page through everything — call
176
+ `browse_data_assets_v2` with `assetTypesFilter: ["AnalyticsWorkspace"]`,
177
+ `sortField: "LastModifiedDate"`, `sortOrder: "Descending"` instead.
178
+
179
+ ## create_semantic_model — surface and recovery
180
+
181
+ - **Param names are `apiName` + `dataspace`, not `name` + `dataSpaceName`.**
182
+ The natural-sounding `name`/`dataSpaceName` guess is rejected — use
183
+ `apiName` (model's developer name) and `dataspace` (lowercase, e.g.
184
+ `"default"`) as shown in the payload below.
185
+ - Nested `semanticDataObjects[].label` is REQUIRED — the server
186
+ rejects without it.
187
+ - **Bind fields in this call.** Each `semanticDataObjects[]` item accepts
188
+ nested `semanticDimensions[]` / `semanticMeasurements[]` with
189
+ `shouldIncludeAllFields: false`. Fetch the DMO/DLO fields first (`run_query`
190
+ `SELECT * … LIMIT 20` or the ingest SCHEMA REALITY CHECK), classify them
191
+ (G5 / Step 0.5), and pass the explicit arrays — including join-key fields
192
+ from Step 3 (e.g. `PartKey`) even if they look like system columns. You
193
+ control each field's `apiName`, so a later `add_semantic_model_relationship`
194
+ resolves first-try. Do **not** use `shouldIncludeAllFields: true` (deprecated;
195
+ numeric-suffix mutation) and do **not** follow with N
196
+ `add_semantic_model_dimension` / `_measure` calls.
197
+ - **Still post-create:** relationships, metrics, calculated fields, parameters,
198
+ and logical views require `add_semantic_model_*` after create. Adding a
199
+ *single extra field* to an already-bound object also uses
200
+ `add_semantic_model_dimension` / `_measure`.
201
+ - **Extend a Model** uses the same tool: pass `baseModels[]` of
202
+ `{ "apiName": "<existing SDM apiName>" }` in the **same `dataspace`**. There is
203
+ no separate extend tool. Typical label `"<Base Label> (Extended)"`.
204
+
205
+ ```jsonc
206
+ // One-call bind. shouldIncludeAllFields:false + explicit nested fields.
207
+ // Include every join-key column from Step 3 (PartKey, account_id__c, …).
208
+ {
209
+ "apiName": "Pipeline_Analysis",
210
+ "dataspace": "default",
211
+ "label": "Pipeline Analysis",
212
+ "description": "Tracks open pipeline opportunities and associated account data for sales forecasting.",
213
+ "sourceCreation": "Other",
214
+ "categories": ["Sales"],
215
+ "semanticDataObjects": [
216
+ {
217
+ "apiName": "Opportunities",
218
+ "label": "Opportunities",
219
+ "description": "Active sales opportunities with stage, amount, and close date",
220
+ "dataObjectName": "opportunities__dlm",
221
+ "dataObjectType": "Dmo",
222
+ "tableType": "Standard",
223
+ "shouldIncludeAllFields": false,
224
+ "semanticDimensions": [
225
+ {
226
+ "apiName": "Stage",
227
+ "label": "Stage",
228
+ "dataObjectFieldName": "stage__c",
229
+ "dataType": "Text",
230
+ "displayCategory": "Discrete",
231
+ "description": "Opportunity sales stage. Values: Prospecting through Closed Won.",
232
+ "isVisible": true
233
+ },
234
+ {
235
+ "apiName": "Account_Id",
236
+ "label": "Account ID",
237
+ "dataObjectFieldName": "account_id__c",
238
+ "dataType": "Text",
239
+ "displayCategory": "Discrete",
240
+ "description": "Join key to Accounts. Record identifier — do not aggregate.",
241
+ "isVisible": true
242
+ },
243
+ {
244
+ "apiName": "DataSource",
245
+ "label": "Data Source",
246
+ "dataObjectFieldName": "DataSource__c",
247
+ "dataType": "Text",
248
+ "isVisible": false
249
+ }
250
+ ],
251
+ "semanticMeasurements": [
252
+ {
253
+ "apiName": "Amount",
254
+ "label": "Amount",
255
+ "dataObjectFieldName": "amount__c",
256
+ "dataType": "Number",
257
+ "aggregationType": "Sum",
258
+ "description": "Gross opportunity amount in org currency. Primary pipeline measure.",
259
+ "sentiment": "SentimentTypeUpIsGood",
260
+ "isVisible": true
261
+ }
262
+ ]
263
+ }
264
+ ]
265
+ }
266
+ ```
267
+
268
+ ```jsonc
269
+ // Same create_semantic_model tool — no separate extend API.
270
+ {
271
+ "apiName": "<NEW_SDM_API_NAME>",
272
+ "dataspace": "default",
273
+ "label": "<Base Label> (Extended)",
274
+ "sourceCreation": "Other",
275
+ "baseModels": [{ "apiName": "<BASE_SDM_API_NAME>" }]
276
+ }
277
+ ```
278
+ - **Bulk-create timeout (>= ~5 objects).** Many `semanticDataObjects[]` in one
279
+ call returns `"Unexpected error while invoking tool postSemanticModelCollection"`
280
+ but the SDM **does persist** ~10–30s later. A naive retry hits
281
+ `"Unique constraint violated"`. Recovery: wait ~30s, then `list_semantic_models`
282
+ to confirm. Prefer create-with-anchor **and its nested fields**, then
283
+ incremental `add_semantic_model_data_object` with the same nested
284
+ `semanticDimensions[]` / `semanticMeasurements[]` shape. If a table has no FK
285
+ to the anchor, add the intermediate first, then bridge through it.
286
+ - Optional final sanity check: `get_semantic_model` with
287
+ `includeModelContent=true`.
288
+
289
+ ## add_semantic_model_measure — agg / type allow-list
290
+
291
+ Create does **not** fully cross-validate `aggregationType` against `dataType` /
292
+ `storageDataType`. Some mismatches return 201 and fail at query time
293
+ (`Cannot convert from TEXT to NUMBER`); others reject at create. Per-type
294
+ allow-list (plus `Auto`, which resolves to the type default):
295
+
296
+ - `Text` / `Boolean`: only `Min`, `Max`, `Count`, `CountDistinct`.
297
+ - `Url` / `Email` / `Phone` / `Geo`: only `Count`, `CountDistinct`.
298
+ - `Number` / `Percentage` / `Currency`: all aggregations.
299
+
300
+ **`dataType: "Currency"` requires a backing record-currency field on the
301
+ DMO.** On a DMO with no `CurrencyIsoCode`-backed column, `Currency` is
302
+ rejected at create — fall back to `dataType: "Number"` for that measure
303
+ instead of retrying `Currency`.
304
+
305
+ Always set `dataType` to match the column's real `storageDataType` from
306
+ `list_semantic_model_dimensions` / `_measures`. PUT on an existing measure also
307
+ skips this allow-list — invalid combos return 200 and fail at query time.
308
+ Changing `aggregationType` on a measure referenced by a metric may break that
309
+ metric — `list_semantic_model_metrics` first.
310
+
311
+ Do not set `externalLevel` or `externalConnectionApiName` on a calculated
312
+ measure unless connecting to an external definition.
313
+
314
+ ## Updates — sparse vs PUT
315
+
316
+ | Tool | Semantics | Must echo / re-send |
317
+ |---|---|---|
318
+ | `update_semantic_model_dimension` / `_measure` | **Sparse** — omitted fields stay put, except `isVisible` | Always echo `isVisible` and `dataObjectFieldName` |
319
+ | `update_semantic_model_data_object` | **Full PUT** | GET via `get_semantic_model_data_object`, send the complete object including nested `semanticDimensions[]` / `semanticMeasurements[]`; a partial body discards omitted nested fields |
320
+ | `update_semantic_model_metric` | **Full PUT** | Re-send `label`, `measurementReference`, `timeDimensionReference`, `insightsSettings` (GET first via `get_semantic_model_metric`) |
321
+ | `update_semantic_model_calculated_dimension` | **Full PUT** | GET via `get_semantic_model_calculated_dimension`, send the complete object (`apiName`, `label`, `expression`, `dataType`, `displayCategory`); omitted fields clear or reset to defaults |
322
+ | `update_semantic_model_calculated_measure` | **Full PUT** | GET via `get_semantic_model_calculated_measure`, send the complete object; omitted fields reset to defaults (`decimalPlace: 2`, `directionality: "Up"`, `sentiment: "SentimentTypeUpIsGood"`, …) |
323
+ | `update_semantic_model_relationship` | **Full PUT** | GET via `get_semantic_model_relationship`, modify, send the returned body back complete. Validate cardinality in the data before changing it. |
324
+ | `update_semantic_model_logical_view` | **PATCH** — only `description`, `filterLogic`, `filters` persist | GET first via `get_semantic_model_logical_view`. Empty body `{}` rejected. Label / SQL / view-type changes are discarded — delete-and-recreate for SQL or type |
325
+ | `update_semantic_model_parameter` | **Full PUT** — not PATCH | Re-send `label`, `type`, `dataType`, `defaultValue` even for a description-only change. `apiName` immutable — omit it. `List` needs `values`. See Parameters. |
326
+ | `update_semantic_model` (model) | Empty/missing body NPEs | Never call with no body |
327
+
328
+ **`isVisible` is NOT preserved by sparse update (server bug).** If a dimension or
329
+ measure is currently `isVisible: false`, omitting `isVisible` silently resets it
330
+ to `true`. Echo it from `list_semantic_model_dimensions` / `_measures` on every
331
+ call, even description-only backfills.
332
+
333
+ ```jsonc
334
+ // Description-only backfill of a hidden measure. Same keys on
335
+ // update_semantic_model_dimension. Do NOT send description alone.
336
+ {
337
+ "modelApiNameOrId": "My_Model",
338
+ "dataObjectNameOrId": "My_Object",
339
+ "measurementNameOrId": "My_Measure",
340
+ "apiName": "My_Measure",
341
+ "dataObjectFieldName": "my_measure__c", // omit → [null] SEMANTIC_FIELD_NOT_VALID
342
+ "isVisible": false, // echoed from list_*; omit → unhides
343
+ "description": "Net revenue after discounts, in org currency."
344
+ }
345
+ ```
346
+
347
+ `apiName` and `dataObjectFieldName` are immutable. Omitting `dataObjectFieldName`
348
+ sends `null` → `SEMANTIC_FIELD_NOT_VALID` / `UPDATE_ENTITY_API_NAME_ERROR`
349
+ ("The referenced Data Cloud fields ([null]) could not be found…"). A wrong
350
+ (non-null) name uses the same error code — distinguish by `[null]` in the
351
+ brackets vs a literal field name. Empty-body dimension/measure updates return
352
+ 500, not 400.
353
+
354
+ `dataType` transitions on a dimension (e.g. Text → Number) are permitted
355
+ without checking `storageDataType`. A mismatch fails at **query** time — read
356
+ `storageDataType` before changing `dataType`.
357
+
358
+ Path exception: metric tools use `metricNameOrId`, not `*ApiNameOrId`.
359
+ `apiName` on a metric PUT is immutable — a different value in the body is
360
+ silently ignored.
361
+
362
+ **Response wrap:** dimension/measure updates return a **flat parsed object** —
363
+ NOT double-wrapped (no `defaultExc` wrapper). Metric / calc-measure /
364
+ relationship updates double-wrap like the add tools. Errors on the unwrapped
365
+ pair use `{enhancedErrorType, message, output}`.
366
+
367
+ Incomplete metric PUT: omitting `measurementReference` → HTTP 500 NPE;
368
+ `{description: "x"}` → `"Required fields are missing: [MasterLabel]"` (the
369
+ payload field is `label`); `{}` → 500 NPE on `Parameter.getValue()`.
370
+
371
+ ## Parameters
372
+
373
+ Parameters cannot be created inline on `create_semantic_model` — they
374
+ require post-create `add_semantic_model_parameter`. Enumerate with
375
+ `list_semantic_model_parameters`. Delete with
376
+ `delete_semantic_model_parameter` (destructive, no undo; success is often
377
+ HTTP 204).
378
+
379
+ ### `update_semantic_model_parameter` — PUT, not PATCH
380
+
381
+ Full payload required every call. MUST re-send `label`, `type`,
382
+ `dataType`, and `defaultValue` even if only changing `description`.
383
+ Incomplete bodies fail validation.
384
+
385
+ - **Inputs:** `modelApiNameOrId`; `parameterApiNameOrId`; `label`; `type`
386
+ (`All` or `List`); `dataType`; `defaultValue`. `description` is optional.
387
+ - **`apiName` is immutable** — omit it from the body. A different value is
388
+ silently ignored.
389
+ - **`dataType` (live tool):** `Boolean` / `Date` / `DateTime` / `Email` /
390
+ `Number` / `Percentage` / `PhoneNumber` / `Text`. **`Url` is not on the
391
+ live sidecar** — do not send it.
392
+ - **`List` type:** `values` is required (array of plain strings) and
393
+ `defaultValue` must exactly match one entry in `values`.
394
+ - **Scope:** current org only.
395
+ - **Response:** the API double-wraps as `{"defaultExc": "<stringified
396
+ JSON>", "responseCode": <number>}`, but the MCP tool unwraps
397
+ transparently — callers receive the parsed parameter object directly.
398
+
399
+ ```jsonc
400
+ // Description-only change still re-sends the full PUT body.
401
+ {
402
+ "modelApiNameOrId": "My_Model",
403
+ "parameterApiNameOrId": "RegionPick",
404
+ "label": "Region",
405
+ "type": "List",
406
+ "dataType": "Text",
407
+ "values": ["East", "West", "Central"],
408
+ "defaultValue": "East", // must match one entry in values
409
+ "description": "Sales territory, not billing geography."
410
+ }
411
+ ```
412
+
413
+ ## Logical views
414
+
415
+ A logical view is a virtual table (pre-joined / filtered / union) without
416
+ modifying base data objects. Enumerate existing ones via `get_semantic_model`
417
+ (`semanticLogicalViews[]`) before creating. `label` is required.
418
+ `Hierarchy` is **not currently supported via MCP**.
419
+
420
+ **HardJoin 3-step** (field apiNames are assigned at first save — unknown in
421
+ advance):
422
+
423
+ 1. `add_semantic_model_logical_view` with `semanticDataObjects` only — **no**
424
+ `semanticRelationships`.
425
+ 2. `get_semantic_model_logical_view` to read assigned field apiNames.
426
+ 3. `add_semantic_model_relationship` with those names. LV joins use `joinType`
427
+ `Left`/`Right`/`Inner`/`Full`, **not** `Auto`.
428
+
429
+ Each LV data-object `apiName` must be unique vs model-level objects
430
+ (`Unique constraint violated` — prefix `LV_`). `dataObjectName` still needs
431
+ `__dll` / `__dlm` / `__dlc`. Auto-bind suffixes still apply — read back before
432
+ joining.
433
+
434
+ ```jsonc
435
+ // HardJoin step 1 — objects only. Do NOT send semanticRelationships here.
436
+ {
437
+ "modelApiNameOrId": "SalesSDM",
438
+ "apiName": "OrdersWithCustomers_LV",
439
+ "label": "Orders with Customers",
440
+ "semanticViewTypeEnum": "HardJoin",
441
+ "semanticDataObjects": [
442
+ {
443
+ "apiName": "LV_Orders",
444
+ "label": "Orders",
445
+ "dataObjectName": "orders__dll",
446
+ "dataObjectType": "Dlo",
447
+ "shouldIncludeAllFields": true
448
+ },
449
+ {
450
+ "apiName": "LV_Customers",
451
+ "label": "Customers",
452
+ "dataObjectName": "customers__dll",
453
+ "dataObjectType": "Dlo",
454
+ "shouldIncludeAllFields": true
455
+ }
456
+ ]
457
+ }
458
+ ```
459
+
460
+ **Union:** all tables live in **exactly one** `semanticUnions[]` entry. Use
461
+ `semanticUnions[]`, not top-level `semanticDataObjects[]`. **Do NOT pass
462
+ `"semanticViewTypeEnum": "Union"`** — the server infers Union from
463
+ `semanticUnions[]` and returns 500 if the enum is set to `"Union"`. GET
464
+ responses may show `semanticViewTypeEnum: "HardJoin"` for a Union (cosmetic
465
+ server bug). `semanticMappedFields[].fields[].fieldApiName` must be the
466
+ **locally-scoped** semantic dim/measure apiName defined on that ULV data
467
+ object — NOT `dataObjectFieldName` and NOT the base model's suffixed names.
468
+ Both fail `"Field API name X not found in either measurements or dimensions."`
469
+ Mapped-field `semanticDimension` / `semanticMeasurement` must be fully
470
+ populated (`apiName`, `label`, `dataObjectFieldName`, `dataType`) or GET 500s
471
+ with `Required fields are missing: [MasterLabel]`. Use `scanMinimalTables: true`
472
+ when the Union is used in a shared-dimension merge model.
473
+
474
+ ```jsonc
475
+ // Union — omit semanticViewTypeEnum. fieldApiName is the local dim/measure
476
+ // apiName (US_OrderId), not order_id__c and not a base-model suffix (Order_Id8).
477
+ {
478
+ "modelApiNameOrId": "SalesSDM",
479
+ "apiName": "AllOrders_LV",
480
+ "label": "All Orders",
481
+ "semanticUnions": [
482
+ {
483
+ "apiName": "AllOrders_ULV",
484
+ "label": "All Orders ULV",
485
+ "semanticDataObjects": [
486
+ {
487
+ "apiName": "LV_Orders_US",
488
+ "label": "Orders US",
489
+ "dataObjectName": "orders_us__dll",
490
+ "dataObjectType": "Dlo",
491
+ "semanticDimensions": [
492
+ {
493
+ "apiName": "US_OrderId",
494
+ "label": "Order ID",
495
+ "dataObjectFieldName": "order_id__c",
496
+ "dataType": "Text"
497
+ }
498
+ ],
499
+ "semanticMeasurements": [
500
+ {
501
+ "apiName": "US_Revenue",
502
+ "label": "Revenue",
503
+ "dataObjectFieldName": "revenue__c",
504
+ "dataType": "Currency",
505
+ "aggregationType": "Sum"
506
+ }
507
+ ]
508
+ },
509
+ {
510
+ "apiName": "LV_Orders_EU",
511
+ "label": "Orders EU",
512
+ "dataObjectName": "orders_eu__dll",
513
+ "dataObjectType": "Dlo",
514
+ "semanticDimensions": [
515
+ {
516
+ "apiName": "EU_OrderId",
517
+ "label": "Order ID",
518
+ "dataObjectFieldName": "order_id__c",
519
+ "dataType": "Text"
520
+ }
521
+ ],
522
+ "semanticMeasurements": [
523
+ {
524
+ "apiName": "EU_Revenue",
525
+ "label": "Revenue",
526
+ "dataObjectFieldName": "revenue__c",
527
+ "dataType": "Currency",
528
+ "aggregationType": "Sum"
529
+ }
530
+ ]
531
+ }
532
+ ],
533
+ "semanticMappedFields": [
534
+ {
535
+ "apiName": "MF_OrderId",
536
+ "label": "Order ID",
537
+ "fields": [
538
+ { "tableApiName": "LV_Orders_US", "fieldApiName": "US_OrderId" },
539
+ { "tableApiName": "LV_Orders_EU", "fieldApiName": "EU_OrderId" }
540
+ ],
541
+ "semanticDimension": {
542
+ "apiName": "MF_OrderId_dim",
543
+ "label": "Order ID",
544
+ "dataObjectFieldName": "order_id__c",
545
+ "dataType": "Text"
546
+ }
547
+ },
548
+ {
549
+ "apiName": "MF_Revenue",
550
+ "label": "Revenue",
551
+ "fields": [
552
+ { "tableApiName": "LV_Orders_US", "fieldApiName": "US_Revenue" },
553
+ { "tableApiName": "LV_Orders_EU", "fieldApiName": "EU_Revenue" }
554
+ ],
555
+ "semanticMeasurement": {
556
+ "apiName": "MF_Revenue_meas",
557
+ "label": "Revenue",
558
+ "dataObjectFieldName": "revenue__c",
559
+ "dataType": "Currency",
560
+ "aggregationType": "Sum"
561
+ }
562
+ }
563
+ ]
564
+ }
565
+ ]
566
+ }
567
+ ```
568
+
569
+ **CustomSQL:** prefer `customSQLV2`. Exactly **one** `semanticDataObjects`
570
+ entry with `dataObjectType: "CustomSQL"`. That entry must have explicit
571
+ dims/measures — `shouldIncludeAllFields: true` does **NOT** satisfy CustomSQL
572
+ validation. Measurements also need `aggregationType`.
573
+
574
+ ```jsonc
575
+ {
576
+ "modelApiNameOrId": "SalesSDM",
577
+ "apiName": "TopCustomers_LV",
578
+ "label": "Top Customers",
579
+ "semanticViewTypeEnum": "CustomSQL",
580
+ "customSQLV2": "SELECT customer_id__c, customer_name__c, SUM(revenue__c) AS total_revenue__c FROM orders__dll GROUP BY customer_id__c, customer_name__c",
581
+ "semanticDataObjects": [
582
+ {
583
+ "apiName": "LV_TopCustomers_SQL",
584
+ "label": "Top Customers SQL",
585
+ "dataObjectName": "orders__dll",
586
+ "dataObjectType": "CustomSQL",
587
+ "semanticDimensions": [
588
+ {
589
+ "apiName": "CustomerId_dim",
590
+ "label": "Customer ID",
591
+ "dataObjectFieldName": "customer_id__c",
592
+ "dataType": "Text"
593
+ },
594
+ {
595
+ "apiName": "CustomerName_dim",
596
+ "label": "Customer Name",
597
+ "dataObjectFieldName": "customer_name__c",
598
+ "dataType": "Text"
599
+ }
600
+ ],
601
+ "semanticMeasurements": [
602
+ {
603
+ "apiName": "TotalRevenue_meas",
604
+ "label": "Total Revenue",
605
+ "dataObjectFieldName": "total_revenue__c",
606
+ "dataType": "Currency",
607
+ "aggregationType": "Sum"
608
+ }
609
+ ]
610
+ }
611
+ ]
612
+ }
613
+ ```
614
+
615
+ `filterLogic` is required when `filters` has more than one entry;
616
+ `filters[].fieldName` is fully qualified `<dataObjectApiName>.<fieldApiName>`.
617
+
618
+ **Updates (PATCH).** `update_semantic_model_logical_view` only persists
619
+ `description`, `filterLogic`, and `filters` — see Updates above. GET first.
620
+ Label is silently ignored. SQL or `semanticViewTypeEnum` changes require
621
+ delete-and-recreate. Empty body `{}` is rejected.
622
+
623
+ ## Tool sequence (happy path)
624
+
625
+ 1. `browse_data_assets` (per AssetType) — discover candidates
626
+ 2. `run_query` `SELECT COUNT(*)` per candidate — verify rows (Step 2)
627
+ 3. `run_query` JOIN probe — confirm keys match (Step 3)
628
+ 4. `run_query` `SELECT * … LIMIT 20` (or ingest SCHEMA REALITY CHECK) — fetch fields, classify (Step 0.5 / G5)
629
+ 5. `create_semantic_model` — one call with nested `semanticDataObjects[]` that include explicit `semanticDimensions[]` / `semanticMeasurements[]` (`shouldIncludeAllFields: false`, join keys included). Extra objects after the anchor: `add_semantic_model_data_object` with the same nested arrays. HardJoin LV objects still use `shouldIncludeAllFields: true` (Logical views).
630
+ 6. `list_semantic_model_data_objects` + `list_semantic_model_dimensions` — light confirm the apiNames you set
631
+ 7. `add_semantic_model_relationship` per key pair (uses the apiNames you set — first-try)
632
+ 8. `list_semantic_model_relationships` — confirm zero islands
633
+ 9. `run_semantic_query` — confirm non-empty cross-object result
634
+
635
+ ## Deleting a semantic definition
636
+
637
+ Component deletes (calculated dimension/measure, metric, data object, logical
638
+ view, relationship) are DESTRUCTIVE with no undo — get explicit user
639
+ confirmation first.
640
+ Whole-asset deletes (`delete_semantic_model` / viz / dashboard / workspace)
641
+ stay on `SKILL.md`. Cross-asset dependents of a viz or dashboard (how many
642
+ dashboards embed this viz) are `list_asset_dependencies` — details in
643
+ `dashboard-authoring.md`, **not** this section's
644
+ `list_semantic_model_dependencies`.
645
+
646
+ Use the real tool names: `delete_semantic_model_calculated_dimension`,
647
+ `delete_semantic_model_calculated_measure`, `delete_semantic_model_metric`,
648
+ `delete_semantic_model_data_object`, `delete_semantic_model_logical_view`,
649
+ `delete_semantic_model_relationship`.
650
+ There is no `delete_semantic_model_calculated_field`. Metric delete does **not**
651
+ cascade to the underlying measure (use `_calculated_measure` separately).
652
+ Confirm the target apiName with `list_*` / `get_*` first. Metric path is
653
+ `metricNameOrId`. For a logical view, confirm with
654
+ `get_semantic_model_logical_view`. For a relationship, confirm with
655
+ `list_semantic_model_relationships`; path is `relationshipNameOrId`.
656
+
657
+ Relationship delete has **no** `relationshipCascadeDelete` escape hatch —
658
+ direct dependents must be removed or repointed manually after the
659
+ `rawEdges: true` preflight. Calculations or metrics that only reference fields
660
+ on the joined objects depend on those **data objects**, not the join, and do
661
+ **not** block deleting the relationship.
662
+
663
+ ### Preflight
664
+
665
+ Call `list_semantic_model_dependencies` with **`rawEdges: true`** before every
666
+ component delete. Default `rawEdges: false` is LOSSY — it collapses every edge
667
+ to the leaf data object, hiding calc-on-calc and metric-on-calc dependents. The
668
+ call still returns **200 OK with a plausible graph** (silent false negative).
669
+
670
+ Optional `types` is **TitleCase** (`CalculatedDimension`,
671
+ `CalculatedMeasurement`, `Metric`, `Relationship`, `LogicalView`), not
672
+ screaming-case. When omitted, defaults to CalculatedDimension and
673
+ CalculatedMeasurement **only** — Metric / Relationship / LogicalView are
674
+ omitted unless you ask.
675
+
676
+ The result is keyed by depender: `definitionApiName` + `dependencies[]`. With
677
+ `rawEdges: true`, dependency `definitionType` / `label` / `modelApiName` may be
678
+ null — rely on `apiName`. **Ignore `fieldApiName`** (null here). To find
679
+ dependents of X, scan entries whose `dependencies[]` contains apiName X. For a
680
+ data object, also scan child dimensions/measures. Scope is the current model
681
+ and its **base models** only — extending-model dependers are not returned.
682
+
683
+ ### Operation ordering
684
+
685
+ Delete is **BLOCKED** if dependents exist. Delete **leaf dependents first**,
686
+ then re-query the graph, then delete this field.
687
+
688
+ | Flag | What it actually clears |
689
+ |---|---|
690
+ | `relationshipCascadeDelete: true` | Dependent **relationship rows** only — **not** calc / metric / LV / dimension dependents. Does **not** touch native columns |
691
+ | Metric delete | **No** cascade escape hatch — clear dependents manually. Does not delete the underlying calc/raw measure |
692
+ | Relationship delete | **No** `relationshipCascadeDelete` escape hatch — remove or repoint direct dependents manually. Calcs/metrics that only reference fields on the joined objects depend on those **data objects**, not the join, and do not block this delete |
693
+ | Data-object delete | Cascade flag auto-removes **joins** that reference the object; calc fields, metrics, and dimensions must be removed first |
694
+
695
+ Set `relationshipCascadeDelete: true` on LV / calc / data-object deletes unless
696
+ you are preserving orphaned relationship rows — still clear non-relationship
697
+ dependents first.
698
+
699
+ ### Recovery
700
+
701
+ - **Multi-dependent errors concatenate entries WITHOUT a separator** (e.g.
702
+ `...CALCULATED_DIMENSIONDependency API name: m_uses_dim...`). Do **not**
703
+ string-parse the error — read dependents from the pre-flight.
704
+ - **Logical-view blocked delete is a different shape.** Calc/metric deletes
705
+ return a clean "can't be deleted because it has dependent elements" message.
706
+ A blocked LV delete currently surfaces as **HTTP 500 with a raw Java stack
707
+ trace** whose root contains `VetoDataChangeException ... DEPENDENCY_EXISTS`
708
+ ("This semantic definition is referenced elsewhere in Salesforce…"). Treat
709
+ 500 + `DEPENDENCY_EXISTS` as a **dependency block, NOT a transient failure —
710
+ do not retry.** The stack does not name the blocker; use the pre-flight.
711
+ - Success is often HTTP 204: `defaultExc` is the literal string `"204"` (not
712
+ JSON-parseable) — branch on `responseCode === 204`.
713
+
714
+ ## Response double-wrap
715
+
716
+ Some tools (e.g. `add_semantic_model_dimension`, `run_query`,
717
+ `run_semantic_query`, `create_workspace`) wrap the body as
718
+ `{"defaultExc": "<stringified JSON>", "responseCode": <number>}`. Parse
719
+ `JSON.parse(response.defaultExc)` to read the result. Read tools like
720
+ `list_semantic_model_*` and `get_dashboard` are NOT wrapped — read fields
721
+ directly.