@salesforce/afv-skills 1.58.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.
- package/package.json +1 -1
- package/skills/agentforce-architecture-analyze/SKILL.md +66 -17
- package/skills/agentforce-architecture-analyze/assets/cli/show_access_token.yaml +4 -7
- package/skills/agentforce-architecture-analyze/references/contract.json +1 -1
- package/skills/agentforce-architecture-analyze/scripts/emit_env.py +2 -2
- package/skills/agentforce-architecture-analyze/scripts/main.py +40 -44
- package/skills/agentforce-architecture-analyze/scripts/rest_client.py +11 -3
- package/skills/agentforce-architecture-analyze/scripts/sf_cli.py +77 -10
- package/skills/agentforce-architecture-analyze/scripts/tests/test_end_to_end_fixture.py +1 -0
- package/skills/agentforce-architecture-analyze/scripts/tests/test_flow_children_inflation.py +1 -0
- package/skills/agentforce-architecture-analyze/scripts/tests/test_main_pipeline.py +53 -2
- package/skills/agentforce-architecture-analyze/scripts/tests/test_resolve_creds.py +184 -36
- package/skills/agentforce-architecture-analyze/scripts/tests/test_rest_client.py +17 -0
- package/skills/agentforce-architecture-analyze/scripts/tests/test_sf_cli.py +165 -11
- package/skills/agentforce-architecture-analyze/scripts/tests/test_skill_md_pipeline_block.py +319 -0
- package/skills/agentforce-bot-upgrade/SKILL.md +3 -1
- package/skills/agentforce-d360-analyze/SKILL.md +28 -10
- package/skills/agentforce-d360-analyze/scripts/dc.py +200 -50
- package/skills/agentforce-d360-analyze/scripts/discover_sessions.py +10 -6
- package/skills/agentforce-d360-analyze/scripts/fetch_dc.py +22 -6
- package/skills/agentforce-d360-analyze/scripts/resolve_session.py +21 -13
- package/skills/agentforce-d360-analyze/scripts/tests/test_dc_and_resolve_session.py +298 -76
- package/skills/agentforce-d360-analyze/scripts/tests/test_default_target_org.py +432 -0
- package/skills/agentforce-d360-analyze/scripts/tests/test_discover_sessions.py +1 -1
- package/skills/agentforce-d360-analyze/scripts/tests/test_resolve_session_main.py +9 -3
- package/skills/agentforce-d360-analyze/scripts/tests/test_skill_md_prefix_block.py +176 -0
- package/skills/agentforce-generate/SKILL.md +21 -1
- package/skills/agentforce-generate/references/known-issues.md +51 -1
- package/skills/agentforce-generate/references/legacy-nga-regression-eval.md +547 -0
- package/skills/agentforce-generate/references/upgrade-legacy-agent-to-agentscript.md +577 -0
- package/skills/agentforce-generate/scripts/upgrade-legacy-nga-analyze.py +404 -0
- package/skills/agentforce-generate/scripts/upgrade-legacy-nga-run-trials.sh +58 -0
- package/skills/agentforce-persona-generate/SKILL.md +505 -0
- package/skills/agentforce-persona-generate/assets/checklist-template.md +100 -0
- package/skills/agentforce-persona-generate/assets/persona-encoding-template.md +252 -0
- package/skills/agentforce-persona-generate/assets/persona-template.md +229 -0
- package/skills/agentforce-persona-generate/assets/sample-dialog-template.md +50 -0
- package/skills/agentforce-persona-generate/assets/workshop-outline-template.md +97 -0
- package/skills/agentforce-persona-generate/examples/concierge-persona.md +189 -0
- package/skills/agentforce-persona-generate/examples/concierge-sample-dialog.md +70 -0
- package/skills/agentforce-persona-generate/examples/drover-persona.md +194 -0
- package/skills/agentforce-persona-generate/examples/drover-sample-dialog.md +62 -0
- package/skills/agentforce-persona-generate/examples/steady-hand-persona.md +188 -0
- package/skills/agentforce-persona-generate/examples/steady-hand-sample-dialog.md +68 -0
- package/skills/agentforce-persona-generate/examples/yt-persona.md +195 -0
- package/skills/agentforce-persona-generate/examples/yt-sample-dialog.md +66 -0
- package/skills/agentforce-persona-generate/references/attributions.md +36 -0
- package/skills/agentforce-persona-generate/references/interaction-design-notes.md +30 -0
- package/skills/agentforce-persona-generate/references/persona-encoding-guide.md +566 -0
- package/skills/agentforce-persona-generate/references/persona-framework.md +796 -0
- package/skills/agentforce-persona-generate/references/refinement-mappings.md +31 -0
- package/skills/agentforce-persona-generate/references/scoring-rubric.md +58 -0
- package/skills/agentforce-persona-generate/references/voice-catalog.json +2327 -0
- package/skills/agentforce-persona-generate/references/workshop-question-policy.md +90 -0
- package/skills/agentforce-persona-generate/references/workshop-scenario-seeds.md +119 -0
- package/skills/agentforce-persona-generate/scripts/parse_agent_yaml.py +223 -0
- package/skills/consumer-goods-accruals-datakit-deploy/SKILL.md +17 -27
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/setup.js +7 -17
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/00-check-prerequisites.js +47 -63
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/01-download-static-resource.js +10 -13
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/02-replace-org-id.js +46 -46
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/03-deploy-metadata.js +4 -21
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/06-create-dataspace.js +58 -82
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/07-deploy-accruals-reports.js +16 -315
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/08-deploy-ui.js +9 -24
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/09-completion.js +44 -44
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/utils.js +11 -63
- package/skills/consumer-goods-rtr-datacloud-export-configure/SKILL.md +2 -1
- package/skills/consumer-goods-tpe-dashboard-configure/SKILL.md +2 -1
- package/skills/consumer-goods-tpe-dashboard-custom-kpi-configure/SKILL.md +2 -1
- package/skills/consumer-goods-tpe-datakit-deploy/SKILL.md +2 -1
- package/skills/data360-schema-get/SKILL.md +3 -3
- package/skills/design-systems-slds-validate/references/report-format.md +1 -1
- package/skills/dx-app-analytics-query/SKILL.md +8 -8
- package/skills/dx-org-manage/SKILL.md +1 -0
- package/skills/dx-org-shape-manage/SKILL.md +1 -0
- package/skills/dx-org-snapshot-manage/SKILL.md +172 -0
- package/skills/dx-org-snapshot-manage/examples/create_error_output.json +16 -0
- package/skills/dx-org-snapshot-manage/examples/create_success_output.json +19 -0
- package/skills/dx-org-snapshot-manage/examples/delete_output.json +9 -0
- package/skills/dx-org-snapshot-manage/examples/get_output.json +19 -0
- package/skills/dx-org-snapshot-manage/examples/list_output.json +36 -0
- package/skills/dx-org-snapshot-manage/references/cli_flags.md +179 -0
- package/skills/dx-org-snapshot-manage/references/snapshot_usage.md +55 -0
- package/skills/dx-org-trial-expiration-check/SKILL.md +1 -1
- package/skills/dx-org-trial-expiration-check/scripts/check_expiration.sh +2 -2
- package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +7 -5
- package/skills/education-cloud-student-recruitment-agent-configure/references/prerequisites.md +11 -11
- package/skills/experience-content-media-image-generate/SKILL.md +83 -0
- package/skills/experience-content-media-image-generate/scripts/download-image.sh +84 -0
- package/skills/experience-ui-bundle-app-coordinate/SKILL.md +12 -12
- package/skills/experience-ui-bundle-app-coordinate/references/phase-completion-validation.md +3 -3
- package/skills/experience-ui-bundle-app-coordinate/references/phase-execution-pattern.md +9 -7
- package/skills/experience-ui-bundle-app-coordinate/scripts/check-dangling-refs.mjs +132 -0
- package/skills/experience-ui-bundle-app-coordinate/scripts/check-hosting-target.mjs +62 -0
- package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-1-complete.mjs +71 -0
- package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-4-complete.mjs +95 -0
- package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-6-ready.mjs +78 -0
- package/skills/experience-ui-bundle-app-coordinate/scripts/check-prerequisites.mjs +21 -0
- package/skills/experience-ui-bundle-app-coordinate/scripts/check-sfdx-project.mjs +28 -0
- package/skills/experience-ui-bundle-custom-app-generate/SKILL.md +3 -1
- package/skills/experience-ui-bundle-custom-app-generate/scripts/resolve-uibundle-path.mjs +40 -0
- package/skills/experience-ui-bundle-frontend-generate/SKILL.md +7 -5
- package/skills/experience-ui-bundle-frontend-generate/scripts/check-preconditions.mjs +70 -0
- package/skills/experience-ui-bundle-frontend-generate/scripts/resolve-ui-bundle.mjs +76 -0
- package/skills/experience-ui-bundle-frontend-generate/scripts/verify-rules.mjs +115 -0
- package/skills/experience-ui-bundle-metadata-generate/SKILL.md +7 -3
- package/skills/experience-ui-bundle-metadata-generate/references/angular-metadata-generate.md +1 -1
- package/skills/experience-ui-bundle-metadata-generate/references/react-metadata-generate.md +1 -1
- package/skills/experience-ui-bundle-metadata-generate/scripts/check-api-version.mjs +43 -0
- package/skills/experience-ui-bundle-metadata-generate/scripts/detect-framework.mjs +131 -0
- package/skills/experience-ui-bundle-metadata-generate/scripts/verify-bundle-location.mjs +152 -0
- package/skills/experience-ui-bundle-mfa-configure/references/branding.md +10 -6
- package/skills/external-diagram-mermaid-generate/SKILL.md +12 -12
- package/skills/field-service-data-capture-migrate/references/component-mapping.md +1 -1
- package/skills/field-service-data-capture-migrate/references/fsm-dc-capability-catalog.md +1 -2
- package/skills/field-service-data-capture-migrate/references/known-deploy-errors.md +1 -0
- package/skills/field-service-data-capture-migrate/references/transformer-rules.md +1 -1
- package/skills/field-service-data-capture-migrate/scripts/transform_flow.py +12 -1
- package/skills/field-service-data-capture-migrate/scripts/vendor/build_flow.py +4 -1
- package/skills/field-service-setup-orchestrator-get/SKILL.md +0 -1
- package/skills/insurance-brokerage-agency-billing-configure/SKILL.md +233 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/accounting-setup.md +117 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/billing-rules-config.md +237 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/billing-settings.md +271 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/demo-policy-config.md +138 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/org-defaults.md +64 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/permissions-config.md +226 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/prerequisites.md +142 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +3 -2
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-execution-state-and-recovery.md +3 -3
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-overview.md +68 -45
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-visit-creation-data.md +17 -18
- package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +16 -3
- package/skills/life-sciences-kam-coordinate/references/stage-5-data-creation-data.md +16 -13
- package/skills/marketing-message-test/SKILL.md +194 -0
- package/skills/marketing-message-test/references/api-contract.md +333 -0
- package/skills/omnistudio-callable-apex-generate/SKILL.md +3 -3
- package/skills/omnistudio-datamapper-generate/SKILL.md +6 -6
- package/skills/omnistudio-datapacks-deploy/SKILL.md +11 -11
- package/skills/omnistudio-dependencies-analyze/SKILL.md +5 -5
- package/skills/omnistudio-epc-catalog-generate/SKILL.md +6 -6
- package/skills/omnistudio-flexcard-generate/SKILL.md +6 -6
- package/skills/omnistudio-integration-procedure-generate/SKILL.md +6 -6
- package/skills/omnistudio-omniscript-generate/SKILL.md +6 -5
- package/skills/platform-apex-logs-debug/SKILL.md +1 -0
- package/skills/platform-metadata-deploy/SKILL.md +1 -0
- package/skills/platform-models-api-configure/SKILL.md +5 -5
- package/skills/platform-soql-query/SKILL.md +1 -0
- package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +17 -6
- package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +107 -192
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone-action.json +6 -6
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +49 -20
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +4 -4
- package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +224 -290
- package/skills/service-itsm-agentic-setup-incident-sla-configure/references/workflow.md +295 -0
- package/skills/service-itsm-incident-priority-configure/SKILL.md +1 -1
- package/skills/service-itsm-slack-itservice-configure/SKILL.md +2 -1
- package/skills/service-itsm-slack-itservice-configure/references/manage-slack-connection.md +2 -2
- package/skills/service-omni-channel-setup-coordinate/SKILL.md +20 -13
- package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +5 -55
- package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +0 -38
- package/skills/service-omni-command-center-analyze/SKILL.md +2 -3
- package/skills/service-omni-command-center-analyze/scripts/analyze.sh +3 -3
- package/skills/tableau-next-asset-create/README.md +65 -0
- package/skills/tableau-next-asset-create/SKILL.md +409 -0
- package/skills/tableau-next-asset-create/references/admin-users.md +149 -0
- package/skills/tableau-next-asset-create/references/ai-readiness.md +355 -0
- package/skills/tableau-next-asset-create/references/alerts.md +111 -0
- package/skills/tableau-next-asset-create/references/build-workflow.md +819 -0
- package/skills/tableau-next-asset-create/references/dashboard-authoring.md +302 -0
- package/skills/tableau-next-asset-create/references/dashboard-design-principles.md +352 -0
- package/skills/tableau-next-asset-create/references/data-transform-gotchas.md +210 -0
- package/skills/tableau-next-asset-create/references/data-understanding.md +387 -0
- package/skills/tableau-next-asset-create/references/deep-reference-index.md +74 -0
- package/skills/tableau-next-asset-create/references/destructive-operations.md +62 -0
- package/skills/tableau-next-asset-create/references/edit-dashboard.md +273 -0
- package/skills/tableau-next-asset-create/references/edit-visualization.md +529 -0
- package/skills/tableau-next-asset-create/references/empty-source-handling.md +104 -0
- package/skills/tableau-next-asset-create/references/ingest-and-metric-gotchas.md +638 -0
- package/skills/tableau-next-asset-create/references/insight-bundle.md +69 -0
- package/skills/tableau-next-asset-create/references/large-flat-file-handling.md +331 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/_envelope.json +54 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/_shared-widget-fields.json +122 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/add_page.json +29 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/delete_page.json +27 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/discard_dashboard.json +11 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/move_widget.json +30 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/move_widget_to_page.json +30 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/place_widget_on_page.json +30 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/remove_widget_from_dashboard.json +16 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/remove_widget_from_page.json +26 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/rename_page.json +28 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/save_dashboard.json +18 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/undo.json +11 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_button_widget.json +69 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_container_widget.json +88 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_filter_widget.json +146 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_metric_widget.json +78 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_navigation_widget.json +80 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_parameter_widget.json +160 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_text_widget.json +103 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_visualization_widget.json +68 -0
- package/skills/tableau-next-asset-create/references/sdm-tool-reference.md +721 -0
- package/skills/tableau-next-asset-create/references/semantic-query-and-enrichment.md +355 -0
- package/skills/tableau-next-asset-create/references/shared-gates.md +322 -0
- package/skills/tableau-next-asset-create/references/sharing-and-promotion.md +306 -0
- package/skills/tableau-next-asset-create/references/tasks/ai-readiness-audit.md +51 -0
- package/skills/tableau-next-asset-create/references/tasks/analyze-data.md +48 -0
- package/skills/tableau-next-asset-create/references/tasks/build-dashboard.md +66 -0
- package/skills/tableau-next-asset-create/references/tasks/build-end-to-end.md +73 -0
- package/skills/tableau-next-asset-create/references/tasks/create-data-transform.md +51 -0
- package/skills/tableau-next-asset-create/references/tasks/create-viz.md +58 -0
- package/skills/tableau-next-asset-create/references/tasks/edit-dashboard.md +80 -0
- package/skills/tableau-next-asset-create/references/tasks/edit-sdm.md +106 -0
- package/skills/tableau-next-asset-create/references/tasks/edit-viz.md +40 -0
- package/skills/tableau-next-asset-create/references/tasks/enrich-model.md +68 -0
- package/skills/tableau-next-asset-create/references/tasks/ingest-flat-file.md +68 -0
- package/skills/tableau-next-asset-create/references/tasks/manage-alert.md +35 -0
- package/skills/tableau-next-asset-create/references/tasks/profile-dataset.md +47 -0
- package/skills/tableau-next-asset-create/references/tasks/promote-or-reuse.md +46 -0
- package/skills/tableau-next-asset-create/references/tasks/provision-user.md +39 -0
- package/skills/tableau-next-asset-create/references/tasks/query-model.md +92 -0
- package/skills/tableau-next-asset-create/references/tasks/review-verified-questions.md +42 -0
- package/skills/tableau-next-asset-create/references/tasks/share-asset.md +37 -0
- package/skills/tableau-next-asset-create/references/verified-questions.md +125 -0
- package/skills/tableau-next-asset-create/references/viz-authoring.md +992 -0
- package/skills/experience-ui-bundle-app-coordinate/scripts/check-dangling-refs.sh +0 -42
- package/skills/experience-ui-bundle-app-coordinate/scripts/check-hosting-target.sh +0 -26
- package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-1-complete.sh +0 -35
- package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-4-complete.sh +0 -47
- package/skills/experience-ui-bundle-app-coordinate/scripts/check-phase-6-ready.sh +0 -33
- package/skills/experience-ui-bundle-app-coordinate/scripts/check-prerequisites.sh +0 -20
- package/skills/experience-ui-bundle-app-coordinate/scripts/check-sfdx-project.sh +0 -15
- package/skills/experience-ui-bundle-custom-app-generate/scripts/resolve-uibundle-path.sh +0 -30
- package/skills/experience-ui-bundle-frontend-generate/scripts/check-preconditions.sh +0 -37
- package/skills/experience-ui-bundle-frontend-generate/scripts/resolve-ui-bundle.sh +0 -66
- package/skills/experience-ui-bundle-frontend-generate/scripts/verify-rules.sh +0 -58
- package/skills/experience-ui-bundle-metadata-generate/scripts/check-api-version.sh +0 -30
- package/skills/experience-ui-bundle-metadata-generate/scripts/detect-framework.sh +0 -73
- package/skills/experience-ui-bundle-metadata-generate/scripts/verify-bundle-location.sh +0 -118
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/predefined-incident-policy.json +0 -102
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
# Semantic Query & Enrichment Reference
|
|
2
|
+
|
|
3
|
+
Field-shape matrix, aggregation mapping, and worked payloads for querying an
|
|
4
|
+
SDM and enriching it with calculated fields and metrics. Substitute apiNames
|
|
5
|
+
from `list_*` — do not copy example names into a live call.
|
|
6
|
+
|
|
7
|
+
> **Our MCP is NOT the REST gateway.** Public/Cursor "semantic-query" guides
|
|
8
|
+
> target `POST /services/data/vXX/semantic-engine/gateway` with a **camelCase**
|
|
9
|
+
> body (`tableField`, `rowGrouping: true`, `semanticAggregationMethod`). The
|
|
10
|
+
> MCP `run_semantic_query` tool takes a **proto-shaped snake_case** body
|
|
11
|
+
> (`table_field`, `grouping: "ROW_GROUPING"`, `semantic_aggregation_method`).
|
|
12
|
+
> Do not copy camelCase payloads — they fail. Use the shapes here.
|
|
13
|
+
|
|
14
|
+
## Contents
|
|
15
|
+
|
|
16
|
+
- run_semantic_query — top-level body (`semantic_context` nested there)
|
|
17
|
+
- Field-shape matrix
|
|
18
|
+
- options block
|
|
19
|
+
- Reading the response
|
|
20
|
+
- Query recovery
|
|
21
|
+
- Worked query (verified): sum of a measure by a joined dimension
|
|
22
|
+
- Detail rows (`detailed_rows: true`)
|
|
23
|
+
- Filtered query (`filter.binary_predicate`)
|
|
24
|
+
- Enrichment — calculated dimension
|
|
25
|
+
- Enrichment — calculated measure
|
|
26
|
+
- Enrichment — metric (named, time-bound KPI)
|
|
27
|
+
|
|
28
|
+
## run_semantic_query — top-level body
|
|
29
|
+
|
|
30
|
+
```jsonc
|
|
31
|
+
{
|
|
32
|
+
"semanticModelApiName": "<SDM apiName>", // NOT semanticModelId (deprecated here)
|
|
33
|
+
"source": "tableau-next-pilot-mcp",
|
|
34
|
+
"dataspace": "default", // omit unless multi-dataspace
|
|
35
|
+
"structuredSemanticQuery": { "fields": [...], "options": {...} }
|
|
36
|
+
// OR structuredMetricQuery — mutually exclusive; do not send both
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Only `fields`, `filter` XOR `flatten_filter` (never both), `options`,
|
|
41
|
+
`semantic_context`, `aggregate_filter`, `parameters` are valid keys inside
|
|
42
|
+
`structuredSemanticQuery`. Putting `limit`, `sort_orders`, or `row_grouping`
|
|
43
|
+
at that level fails with `Cannot find field: <key>`. Prefer
|
|
44
|
+
`options.limit_options.limit` + `sort_orders` for top-N over proto
|
|
45
|
+
`top_n_filter`.
|
|
46
|
+
|
|
47
|
+
Pass **ONE** of `structuredSemanticQuery` (recommended) **OR**
|
|
48
|
+
`structuredMetricQuery` (alternative) — mutually exclusive dispatch paths.
|
|
49
|
+
Do not send both. Outer-request `context` (`timezone`, `locale`) is distinct
|
|
50
|
+
from per-query `semantic_context`. Most queries omit `semantic_context` — the
|
|
51
|
+
engine picks defaults. Pass it when fiscal-year filters or timezone-sensitive
|
|
52
|
+
date math matters:
|
|
53
|
+
|
|
54
|
+
```jsonc
|
|
55
|
+
"semantic_context": {
|
|
56
|
+
"timezone": { "id": "America/Los_Angeles" },
|
|
57
|
+
"locale": { "code": "en_US" }
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Query is org-level / SDM-level — it does **NOT** take a `workspaceId`. Any SDM
|
|
62
|
+
visible via `list_semantic_models` is queryable regardless of workspace.
|
|
63
|
+
|
|
64
|
+
Treat any **2xx** as success (the wrapper has been observed to return 201).
|
|
65
|
+
Provisioning is gated on `orgHasDataCloudReportingEnabled` OR
|
|
66
|
+
`orgHasSemanticQuery` — a permission error is a **provisioning gap**, not a
|
|
67
|
+
caller payload bug.
|
|
68
|
+
|
|
69
|
+
## Field-shape matrix
|
|
70
|
+
|
|
71
|
+
| Field kind | expression | grouping / aggregation |
|
|
72
|
+
|---|---|---|
|
|
73
|
+
| **Raw dimension** | `{ "table_field": { "name": "<dimApiName>", "table_name": "<objApiName>" } }` | `"grouping": "ROW_GROUPING"` |
|
|
74
|
+
| **Raw measure** | `{ "table_field": { "name": "<measApiName>", "table_name": "<objApiName>" } }` | `"semantic_aggregation_method": "SEMANTIC_AGGREGATION_METHOD_<AGG>"` |
|
|
75
|
+
| **Calculated dimension** | `{ "semantic_field": { "name": "<calcDimApiName>" } }` | `"grouping": "ROW_GROUPING"` |
|
|
76
|
+
| **Calculated measure** | `{ "semantic_field": { "name": "<calcMeasApiName>" } }` | `"semantic_aggregation_method": "SEMANTIC_AGGREGATION_METHOD_USER_AGG"` (for AVG/ratio/COUNTD expressions) |
|
|
77
|
+
|
|
78
|
+
- `table_name` MUST be the SDM **data-object apiName** from
|
|
79
|
+
`list_semantic_model_data_objects` — NOT the `__dll`/`__dlm` source name
|
|
80
|
+
(that → `Failed to resolve table`).
|
|
81
|
+
- `name` MUST be the **suffixed** field apiName from
|
|
82
|
+
`list_semantic_model_dimensions` / `list_semantic_model_measures`.
|
|
83
|
+
- `semantic_field` is ONLY for **calculated** SDM fields. It takes ONLY
|
|
84
|
+
`name` (no `table_name`). Using `semantic_field` for a raw/physical column
|
|
85
|
+
fails `Failed to resolve semantic field <name>...`. Rule of thumb:
|
|
86
|
+
calculated → `semantic_field`; physical column → `table_field`.
|
|
87
|
+
- `alias` convention: `"<objApiName>.<fieldApiName>"` for table fields,
|
|
88
|
+
`"<apiName>"` for semantic (calculated) fields.
|
|
89
|
+
- A third shape, on-the-fly `calculated_field`, exists; prefer a pre-defined
|
|
90
|
+
calc on the model over inventing one in the query.
|
|
91
|
+
- **In an aggregated query, every measure needs `semantic_aggregation_method`.**
|
|
92
|
+
A measure with no aggregation is treated as a detail row and errors
|
|
93
|
+
`Detail Rows with Metric must have the corresponding dimension` — this fires
|
|
94
|
+
on the **MISSING aggregation**, NOT a missing dimension (adding
|
|
95
|
+
`ROW_GROUPING` does NOT satisfy it). A grouping dimension is optional
|
|
96
|
+
(measure-only = grand total). **Exception:** `options.detailed_rows: true` is
|
|
97
|
+
the one shape where omitting the aggregation method is valid.
|
|
98
|
+
|
|
99
|
+
### Aggregation method enum
|
|
100
|
+
|
|
101
|
+
Valid query-time suffixes only: `SUM`, `AVG`, `COUNT`, `MIN`, `MAX`,
|
|
102
|
+
`UNIQUE_COUNT`, `USER_AGG`. Map the model's `aggregationType` enum value (left)
|
|
103
|
+
to the query-time suffix (right): `Sum→SUM`, `Average→AVG`, `Count→COUNT`,
|
|
104
|
+
`CountDistinct→UNIQUE_COUNT`, `Min→MIN`, `Max→MAX`. Note the model enum uses
|
|
105
|
+
`Average` (not `Avg`), and there is no `SEMANTIC_AGGREGATION_METHOD_COUNTDISTINCT`
|
|
106
|
+
at query time — `CountDistinct` maps to `SEMANTIC_AGGREGATION_METHOD_UNIQUE_COUNT`,
|
|
107
|
+
a distinct enum value from plain `COUNT` (`COUNT` counts all rows; `UNIQUE_COUNT`
|
|
108
|
+
counts distinct values). A calculated measure whose expression already
|
|
109
|
+
aggregates uses `USER_AGG`.
|
|
110
|
+
|
|
111
|
+
## options block
|
|
112
|
+
|
|
113
|
+
```jsonc
|
|
114
|
+
"options": {
|
|
115
|
+
"limit_options": { "limit": 10 },
|
|
116
|
+
"sort_orders": [ { "simple_sort_order": { "sort_by_field_alias": "<alias>", "sorting_order": "DESC" } } ],
|
|
117
|
+
"grand_total": true // OR "detailed_rows": true — never both
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
- Aggregate query (≥1 measure/calc measure): `grand_total: true` adds a total
|
|
122
|
+
row. Detail query (dimensions only): `detailed_rows: true`. (These two
|
|
123
|
+
option flags are documented independently in the schema; whether they
|
|
124
|
+
combine is **unverified** — the worked query below used neither.)
|
|
125
|
+
- Aggregate queries should include ≥1 dimension with `ROW_GROUPING` (a
|
|
126
|
+
measure-only query returns a single grand-total row — valid for "total X").
|
|
127
|
+
|
|
128
|
+
## Reading the response
|
|
129
|
+
|
|
130
|
+
Double-wrapped: parse `JSON.parse(response.defaultExc)`. Treat any **2xx** as
|
|
131
|
+
success (wrapper has been observed to return 201). Then:
|
|
132
|
+
`status === "SUCCESS"`; `queryResults.queryMetadata.fields[<alias>].placeInOrder`
|
|
133
|
+
indexes into each `queryResults.queryData.rows[i].values[]`. A `null` grouping
|
|
134
|
+
value is the unmatched/blank bucket (verified: a `null` region row appeared
|
|
135
|
+
alongside the real groups). `status != "SUCCESS"` is a failure — read
|
|
136
|
+
`errorMessage`. `status != "SUCCESS"` with an **empty** `errorMessage` is an
|
|
137
|
+
unknown failure — ask the user to check the org's CDP / Reporting
|
|
138
|
+
configuration. A confirmed **permission** error is the provisioning-gap
|
|
139
|
+
signal (`orgHasDataCloudReportingEnabled` / `orgHasSemanticQuery`), not a
|
|
140
|
+
caller payload bug.
|
|
141
|
+
|
|
142
|
+
**Display rules.** Render rows as a markdown table for ≤20 rows, else row
|
|
143
|
+
count + first 10 + "… and N more". Order by `placeInOrder`. Do **NOT** echo
|
|
144
|
+
the raw `queryResults` JSON. Surface `errorMessage` verbatim on failure.
|
|
145
|
+
|
|
146
|
+
## Query recovery
|
|
147
|
+
|
|
148
|
+
| Signal | Cause / fix |
|
|
149
|
+
|---|---|
|
|
150
|
+
| `Failed to resolve table` | Used `__dll`/`__dlm` instead of the SDM data-object apiName |
|
|
151
|
+
| `Failed to resolve semantic field` | Used `semantic_field` for a raw/physical column — use `table_field` |
|
|
152
|
+
| `Cannot find field: <key>` | Non-proto top-level key (`limit`/`sort_orders`/`row_grouping` outside `options`) |
|
|
153
|
+
| `Query returns more records than allowed. The limit is: 5000` | Add `limit_options` or aggregate |
|
|
154
|
+
| `USER_ILLEGAL_ARGUMENT_RESOLVE_ENTITY_ERROR` | Typo / wrong table / physical column as `table_field.name` |
|
|
155
|
+
| `Detail Rows with Metric must have the corresponding dimension` | Missing `semantic_aggregation_method` on a measure (not a missing dimension) |
|
|
156
|
+
| Permission error | `orgHasDataCloudReportingEnabled` / `orgHasSemanticQuery` provisioning gap |
|
|
157
|
+
| `status != SUCCESS` with empty `errorMessage` | Unknown failure — check org CDP / Reporting configuration |
|
|
158
|
+
|
|
159
|
+
## Worked query (verified): sum of a measure by a joined dimension
|
|
160
|
+
|
|
161
|
+
```jsonc
|
|
162
|
+
{
|
|
163
|
+
"semanticModelApiName": "ZZ_Trap_base0",
|
|
164
|
+
"source": "tableau-next-pilot-mcp",
|
|
165
|
+
"structuredSemanticQuery": {
|
|
166
|
+
"fields": [
|
|
167
|
+
{ "expression": { "table_field": { "name": "region18", "table_name": "Accounts" } },
|
|
168
|
+
"alias": "Accounts.region18", "grouping": "ROW_GROUPING" },
|
|
169
|
+
{ "expression": { "table_field": { "name": "Amount7", "table_name": "Opportunities" } },
|
|
170
|
+
"alias": "Opportunities.Amount7",
|
|
171
|
+
"semantic_aggregation_method": "SEMANTIC_AGGREGATION_METHOD_SUM" }
|
|
172
|
+
],
|
|
173
|
+
"options": { "limit_options": { "limit": 10 },
|
|
174
|
+
"sort_orders": [ { "simple_sort_order": { "sort_by_field_alias": "Opportunities.Amount7", "sorting_order": "DESC" } } ] }
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Returned per-region sums by traversing the Accounts↔Opportunities join.
|
|
180
|
+
|
|
181
|
+
## Detail rows (`detailed_rows: true`)
|
|
182
|
+
|
|
183
|
+
The one shape where a measure may omit `semantic_aggregation_method`. Do not
|
|
184
|
+
also set `grand_total`. Field names below are illustrative — copy apiNames from
|
|
185
|
+
`list_*`.
|
|
186
|
+
|
|
187
|
+
```jsonc
|
|
188
|
+
{
|
|
189
|
+
"semanticModelApiName": "Sales_Performance_SDM",
|
|
190
|
+
"structuredSemanticQuery": {
|
|
191
|
+
"fields": [
|
|
192
|
+
{ "expression": { "table_field": { "name": "Account_ID", "table_name": "Account" } },
|
|
193
|
+
"alias": "account_id" },
|
|
194
|
+
{ "expression": { "table_field": { "name": "Account_Name", "table_name": "Account" } },
|
|
195
|
+
"alias": "account_name" },
|
|
196
|
+
{ "expression": { "table_field": { "name": "Revenue", "table_name": "Account" } },
|
|
197
|
+
"alias": "revenue" }
|
|
198
|
+
],
|
|
199
|
+
"options": {
|
|
200
|
+
"detailed_rows": true,
|
|
201
|
+
"limit_options": { "limit": 20 }
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
"dataspace": "default"
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Filtered query (`filter.binary_predicate`)
|
|
209
|
+
|
|
210
|
+
`filter` XOR `flatten_filter` — never both. Count-distinct uses
|
|
211
|
+
`SEMANTIC_AGGREGATION_METHOD_UNIQUE_COUNT` (not `COUNTDISTINCT`).
|
|
212
|
+
|
|
213
|
+
```jsonc
|
|
214
|
+
{
|
|
215
|
+
"semanticModelApiName": "Sales_Performance_SDM",
|
|
216
|
+
"structuredSemanticQuery": {
|
|
217
|
+
"fields": [
|
|
218
|
+
{
|
|
219
|
+
"expression": {
|
|
220
|
+
"table_field": { "name": "Account_ID", "table_name": "Account" }
|
|
221
|
+
},
|
|
222
|
+
"semantic_aggregation_method": "SEMANTIC_AGGREGATION_METHOD_UNIQUE_COUNT",
|
|
223
|
+
"alias": "distinct_accounts"
|
|
224
|
+
}
|
|
225
|
+
],
|
|
226
|
+
"filter": {
|
|
227
|
+
"binary_predicate": {
|
|
228
|
+
"left_expression": { "table_field": { "name": "Segment", "table_name": "Account" } },
|
|
229
|
+
"binary_operator": "BINARY_OPERATOR_EQUALS",
|
|
230
|
+
"right_expression": { "string_expression": "Enterprise" }
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Enrichment — calculated dimension
|
|
238
|
+
|
|
239
|
+
`add_semantic_model_calculated_dimension`. TuA expression with **bracketed
|
|
240
|
+
qualified references** `[ObjApiName].[FieldApiName]` (suffixed apiNames). Bare
|
|
241
|
+
identifiers fail with "Missing reference". Verified:
|
|
242
|
+
|
|
243
|
+
```jsonc
|
|
244
|
+
{
|
|
245
|
+
"modelApiNameOrId": "ZZ_Trap_base0",
|
|
246
|
+
"apiName": "Region_Upper",
|
|
247
|
+
"label": "Region Upper",
|
|
248
|
+
"expression": "UPPER([Accounts].[region18])",
|
|
249
|
+
"dataType": "Text",
|
|
250
|
+
"displayCategory": "Discrete"
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Row-level expression → server sets `level: "Row"` automatically.
|
|
255
|
+
|
|
256
|
+
- Calculated-measure TuA conditionals are **simple CASE only**:
|
|
257
|
+
`CASE <expr> WHEN <value> THEN <result> ... [ELSE <result>] END`.
|
|
258
|
+
Searched CASE (`CASE WHEN <condition> THEN ...`) and `IF(condition, then, else)`
|
|
259
|
+
are rejected (`Syntax Error - no viable alternative at input 'WHEN'` /
|
|
260
|
+
`mismatched input ','`). Key the CASE off a value, not a boolean predicate.
|
|
261
|
+
Block `IF`/`ELSEIF`/`END` and `IIF(...)` are **pending live verification** —
|
|
262
|
+
do not use them in a calc measure or dimension until confirmed.
|
|
263
|
+
|
|
264
|
+
## Enrichment — calculated measure
|
|
265
|
+
|
|
266
|
+
`add_semantic_model_calculated_measure`. Verified (level-aware AVG):
|
|
267
|
+
|
|
268
|
+
```jsonc
|
|
269
|
+
{
|
|
270
|
+
"modelApiNameOrId": "ZZ_Trap_base0",
|
|
271
|
+
"apiName": "Avg_Deal_Size",
|
|
272
|
+
"label": "Avg Deal Size",
|
|
273
|
+
"expression": "AVG([Opportunities].[Amount7])",
|
|
274
|
+
"dataType": "Number",
|
|
275
|
+
"aggregationType": "UserAgg", // required when the expression aggregates
|
|
276
|
+
"displayCategory": "Continuous"
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
- Expression that already aggregates (`AVG`, `SUM/COUNT`, `COUNTD`) → must use
|
|
281
|
+
`aggregationType: "UserAgg"`; a bare `Average`/`Sum` is rejected with
|
|
282
|
+
"AggregativeFunction-level calculated fields require UserAgg". Server sets
|
|
283
|
+
`level: "AggregateFunction"`.
|
|
284
|
+
- Row-level arithmetic (`[O].[Profit] / [O].[Sales]`) → `aggregationType: "Auto"`.
|
|
285
|
+
- The server overlays defaults that were not passed (`decimalPlace: 2`,
|
|
286
|
+
`directionality: "Up"`, `sentiment`, `totalAggregationType: "Sum"`,
|
|
287
|
+
`level: "Row"`, `shouldTreatNullsAsZeros: false`) — set them explicitly to
|
|
288
|
+
override.
|
|
289
|
+
- No arithmetic check: `/ 0` is accepted and fails only at query time.
|
|
290
|
+
- Do not set `externalLevel` or `externalConnectionApiName` unless connecting
|
|
291
|
+
to an external definition.
|
|
292
|
+
- Updates are **full PUT**: GET via `get_semantic_model_calculated_measure`,
|
|
293
|
+
then send the complete object. Omitted fields reset to those defaults.
|
|
294
|
+
|
|
295
|
+
To query a UserAgg calc measure, reference it as a `semantic_field` with
|
|
296
|
+
`SEMANTIC_AGGREGATION_METHOD_USER_AGG` (verified returning per-group averages).
|
|
297
|
+
|
|
298
|
+
## Enrichment — metric (named, time-bound KPI)
|
|
299
|
+
|
|
300
|
+
`add_semantic_model_metric`. `label` is required. **Create a metric by default
|
|
301
|
+
when the request implies a tracked business number** (revenue, win rate,
|
|
302
|
+
engagement, count over time) **and a business-meaningful event date exists to
|
|
303
|
+
anchor it** — not only on explicit demand. Set EXACTLY ONE shape on
|
|
304
|
+
`measurementReference` (and on `timeDimensionReference`). Verified shape:
|
|
305
|
+
|
|
306
|
+
```jsonc
|
|
307
|
+
{
|
|
308
|
+
"modelApiNameOrId": "Pipeline_Analysis",
|
|
309
|
+
"apiName": "Total_Pipeline",
|
|
310
|
+
"label": "Total Pipeline",
|
|
311
|
+
"measurementReference": { "tableFieldReference": { "tableApiName": "Opportunities", "fieldApiName": "Amount7" } },
|
|
312
|
+
// OR a derived measure: "measurementReference": { "calculatedFieldApiName": "Avg_Deal_Size" }
|
|
313
|
+
"timeDimensionReference": { "tableFieldReference": { "tableApiName": "Opportunities", "fieldApiName": "Created_Date14" } },
|
|
314
|
+
"aggregationType": "Sum", // matches the RAW-measure branch (sum of Amount). For the
|
|
315
|
+
// calculatedFieldApiName branch, set the calc field's own
|
|
316
|
+
// aggregation (e.g. "UserAgg" for Avg_Deal_Size) — do NOT Sum an average.
|
|
317
|
+
"timeGrains": ["Day", "Week", "Month", "Quarter", "Year"],
|
|
318
|
+
"insightsSettings": { // REQUIRED — omit identifyingDimension and the metric UI crashes
|
|
319
|
+
"identifyingDimension": {
|
|
320
|
+
"identifierDimensionReference": {
|
|
321
|
+
"tableFieldReference": { "tableApiName": "Opportunities", "fieldApiName": "Opportunity_Id5" }
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
"additionalDimensions": [ // must include identifyingDimension (and every insights/filter field)
|
|
326
|
+
{ "tableFieldReference": { "tableApiName": "Opportunities", "fieldApiName": "Opportunity_Id5" } }
|
|
327
|
+
]
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Do not ship this block without `insightsSettings`, and always mirror
|
|
332
|
+
`identifyingDimension` into `additionalDimensions` (create fails with
|
|
333
|
+
`Insight dimension (...) is missing from the metric additional dimensions`).
|
|
334
|
+
Nouns, extra `additionalDimensions`, and `insightsDimensionsReferences` live in
|
|
335
|
+
`ingest-and-metric-gotchas.md` §B and `build-workflow.md` Step 8.
|
|
336
|
+
|
|
337
|
+
- `aggregationType` enum values: `Sum`, `Average`, `Count`, `CountDistinct`,
|
|
338
|
+
`Min`, `Max`, `UserAgg`, `Auto`, etc. (note `Average`, not `Avg`).
|
|
339
|
+
- `fieldApiName` on BOTH references is the **suffixed** apiName **from the
|
|
340
|
+
object that owns the field**. A date field from a *different* object is
|
|
341
|
+
rejected with `Table field with table name: (X) and field name: (Y) was not
|
|
342
|
+
found in the model` (the exact error hit when an Accounts date dim was passed
|
|
343
|
+
for an Opportunities reference). Read each object's own dimensions with
|
|
344
|
+
`list_semantic_model_dimensions` and match the owner.
|
|
345
|
+
- The time dimension must be a **business-meaningful** `Date`/`DateTime`
|
|
346
|
+
dimension (`dataType: "Date"`) — a real event date (created/close/order/
|
|
347
|
+
activity), NOT a `cdp_sys_PartitionDate`, `*_SourceVersion`, or load
|
|
348
|
+
timestamp. A metric on a plumbing date is worse than no metric.
|
|
349
|
+
- With `filters`, also pass `filterLogic` (e.g. `"1"` / `"1 AND 2"`) and
|
|
350
|
+
fully-qualify filter `fieldName` as `<tableApiName>.<fieldApiName>`.
|
|
351
|
+
- Skip the metric only if no meaningful date dimension resolves.
|
|
352
|
+
- Pass **ONE** of `structuredSemanticQuery` **OR** `structuredMetricQuery` on
|
|
353
|
+
`run_semantic_query` — mutually exclusive. Prefer `structuredMetricQuery`
|
|
354
|
+
when querying a named metric (see `build-workflow.md` Step 9). Do not
|
|
355
|
+
reconstruct the metric from raw fields unless no metric exists.
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# Shared Gates (G1–G8) — the single source of truth
|
|
2
|
+
|
|
3
|
+
Every task guide under `references/tasks/` opens with a **gate header** that
|
|
4
|
+
names the gates it must assert (e.g. "Required: G1, G3, G7"). This file is where
|
|
5
|
+
each gate's *authoritative rule → how to check it → what to do on failure* lives —
|
|
6
|
+
in exactly one place. A guide names a gate and may give a **one-line, non-normative
|
|
7
|
+
reminder** so it reads on its own; it must **not** restate the authoritative rule.
|
|
8
|
+
If a gate's rule ever changes, it changes **here** — the guide reminders are
|
|
9
|
+
pointers, not a second copy to keep in sync.
|
|
10
|
+
|
|
11
|
+
**Legend used in the guide headers:** ● = required · ◐ = conditional (only if the
|
|
12
|
+
action touches >1 object, adds a new join, or references a formula/field it did
|
|
13
|
+
not just read back).
|
|
14
|
+
|
|
15
|
+
**Tool-name convention (single source of truth).** The MCP tools are exposed
|
|
16
|
+
under a `tableau-next-*` server. Everywhere in this skill — gates, router, task
|
|
17
|
+
guides — tool names are written **bare** (e.g. `add_semantic_model_relationship`)
|
|
18
|
+
for readability. Invoke each under whatever name your client advertises for that
|
|
19
|
+
server's tool (Claude Code, for example, exposes it as
|
|
20
|
+
`mcp__tableau-next-pilot-production__add_semantic_model_relationship`); match the
|
|
21
|
+
advertised name rather than hand-constructing one. Guides cite this line; they do
|
|
22
|
+
not restate it.
|
|
23
|
+
|
|
24
|
+
## Contents
|
|
25
|
+
|
|
26
|
+
- G1 — MCP-server-connected precondition
|
|
27
|
+
- G2 — Data presence is the gate (row-count > 0, re-verified at use time)
|
|
28
|
+
- G3 — Never invent an apiName (read it back via `list_*`)
|
|
29
|
+
- G4 — No island objects
|
|
30
|
+
- G5 — AI-readiness metadata (+ coverage checks)
|
|
31
|
+
- G6 — Data-understanding profiling
|
|
32
|
+
- G7 — Query-returns-real-data validation
|
|
33
|
+
- G8 — Narrative-design-first (decision #1 — scoped)
|
|
34
|
+
- G-notes (shapes cited by the gates, kept here so guides don't re-type them)
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## G1 — MCP-server-connected precondition
|
|
39
|
+
|
|
40
|
+
**RULE.** Every action in this skill drives a Tableau Next MCP server; without one
|
|
41
|
+
connected there is nothing to call. Never fabricate a tool call or a result
|
|
42
|
+
against a server that is not there.
|
|
43
|
+
|
|
44
|
+
**CHECK.** Confirm the available tools include one prefixed `mcp__tableau-next-*__`
|
|
45
|
+
(e.g. `mcp__tableau-next-pilot-production__browse_data_assets`,
|
|
46
|
+
`mcp__tableau-next-self-service__create_semantic_model`). Server names vary
|
|
47
|
+
(`tableau-next-pilot-*`, `tableau-next-self-service`, …) — match the
|
|
48
|
+
`tableau-next` stem, not an exact name.
|
|
49
|
+
|
|
50
|
+
**ON FAILURE.** If NO such tool is present, **STOP.** Do not attempt the workflow,
|
|
51
|
+
do not describe payloads as if you had run them, and never invent tool
|
|
52
|
+
calls/results/IDs. Tell the user the skill requires a connected Tableau Next MCP
|
|
53
|
+
server, name concrete examples (`tableau-next-pilot-*`, `tableau-next-self-service`),
|
|
54
|
+
and ask them to connect one and re-invoke. This is the difference between "I built
|
|
55
|
+
your dashboard" and a hallucinated transcript of one.
|
|
56
|
+
|
|
57
|
+
> G1 is universal, so it is asserted **once in the router** (`SKILL.md`) and
|
|
58
|
+
> inherited by every entry point — including non-build standalone intents ("add a
|
|
59
|
+
> metric" with no server still STOPs). No guide re-implements it, but every guide
|
|
60
|
+
> depends on it.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## G2 — Data presence is the gate (row-count > 0, re-verified at use time)
|
|
65
|
+
|
|
66
|
+
**RULE.** Never build on an object with zero rows. A source with zero rows
|
|
67
|
+
produces an empty visualization no matter how many fields it has, and no join
|
|
68
|
+
fixes it. **Field-richness is not data-presence** — a canonical-looking DMO can
|
|
69
|
+
have 66 fields and 0 rows. Row presence is verified **at use time**, not assumed
|
|
70
|
+
"populated once."
|
|
71
|
+
|
|
72
|
+
**CHECK.** For every *externally discovered* candidate, run `SELECT COUNT(*)`
|
|
73
|
+
(or equivalent) before adding it to a model and before charting it.
|
|
74
|
+
`count > 0` = usable; `count = 0` = empty (see G-note below); a
|
|
75
|
+
`table "X__dlm" does not exist` / `42P01` error = unmaterialized, which is
|
|
76
|
+
distinct from empty — see `empty-source-handling.md`.
|
|
77
|
+
|
|
78
|
+
- **Ingest post-condition:** a freshly created file DLO has 0 rows until
|
|
79
|
+
`run_data_stream` runs. Run the stream, then wait until the DLO is Active
|
|
80
|
+
(`ingest-and-metric-gotchas.md` §A). Row presence is a stand-in for ready, not
|
|
81
|
+
the same thing.
|
|
82
|
+
- **Self-created mapping — query readiness, not status:** for a DMO you just
|
|
83
|
+
created and mapped in this same flow, **`get_dlo_to_dmo_mapping_status`
|
|
84
|
+
`ACTIVE` is not a readiness signal.** It means mapping metadata deployed
|
|
85
|
+
off-core; it does **not** mean `<dmo>__dlm` exists. Poll `run_query`
|
|
86
|
+
`SELECT 1 FROM <dmo>__dlm LIMIT 1` (or `SELECT COUNT(*)`). `42P01` /
|
|
87
|
+
"table does not exist" = NOT-READY — keep polling. Any success, including
|
|
88
|
+
`COUNT = 0`, = READY (table is queryable; proceed to SDM). Use
|
|
89
|
+
`get_dlo_to_dmo_mapping_status` to inspect the mapping and to detect
|
|
90
|
+
`ERROR` / `INACTIVE` — not as the query-readiness gate. Keep the
|
|
91
|
+
discovered-source hard gate as-is: `COUNT = 0` on a pre-existing object
|
|
92
|
+
still means do not build on it.
|
|
93
|
+
- **`isEnabled: false` right after DMO creation is normal.** Check it, but do
|
|
94
|
+
not gate on it and do not wait for it before mapping — expected transient
|
|
95
|
+
state, not a readiness signal.
|
|
96
|
+
|
|
97
|
+
**ON FAILURE.** If a *discovered* candidate has zero rows, refuse to build on it
|
|
98
|
+
and surface it to the user; do not put a measure/dimension from an unverified
|
|
99
|
+
object on a viz. If no discovered candidate has rows, STOP and tell the user the
|
|
100
|
+
sources are empty rather than shipping a blank dashboard. Do not treat
|
|
101
|
+
`COUNT = 0` on a DMO you just mapped in this flow as that failure (READY). Do
|
|
102
|
+
not treat `42P01` on that DMO as "unmaterialized, exclude" — keep polling.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## G3 — Never invent an apiName (read it back via `list_*`)
|
|
107
|
+
|
|
108
|
+
**RULE.** The server mutates field/object apiNames on bind — bulk import
|
|
109
|
+
(`shouldIncludeAllFields: true`) suffixes every apiName differently per object
|
|
110
|
+
(`Region__c` → `Region4`; `account_id__c` → `account_id5` on one object,
|
|
111
|
+
`account_id3` on another). Do **not** use that flag for model-level bind
|
|
112
|
+
(deprecated). Nested explicit fields (`semanticDimensions[]` /
|
|
113
|
+
`semanticMeasurements[]` on `create_semantic_model` /
|
|
114
|
+
`add_semantic_model_data_object`) come back as the apiNames you set.
|
|
115
|
+
|
|
116
|
+
**CHECK.** Before typing any apiName you did not read back this session, call the
|
|
117
|
+
relevant `list_*` tool (`list_semantic_model_dimensions` / `_measures` /
|
|
118
|
+
`_data_objects` / `_calculated_*` / `_metrics`) and copy the exact stored value.
|
|
119
|
+
In a relationship, use the semantic apiName with `leftFieldType: "TableField"`
|
|
120
|
+
(not the raw `dataObjectFieldName`).
|
|
121
|
+
|
|
122
|
+
**ON FAILURE.** If you are about to write an apiName you have not read back this
|
|
123
|
+
session, STOP and read it back first. Never assume the two sides of a join share a
|
|
124
|
+
suffix.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## G4 — No island objects
|
|
129
|
+
|
|
130
|
+
**RULE.** In a model with two or more objects, every object must participate in at
|
|
131
|
+
least one relationship. (This is secondary to G2: it does not catch a single empty
|
|
132
|
+
object — G2 does.)
|
|
133
|
+
|
|
134
|
+
**CHECK.** After adding objects, confirm every object is on at least one
|
|
135
|
+
relationship. The gate fires once the model has ≥2 objects; a newly added object
|
|
136
|
+
must not be left an island.
|
|
137
|
+
|
|
138
|
+
**ON FAILURE.** Add the missing relationship(s) — validated by G7 — before
|
|
139
|
+
declaring the model done. Do not set `queryUnrelatedDataObjects: "Exception"` and
|
|
140
|
+
then query across unjoined objects (it throws, not warns).
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## G5 — AI-readiness metadata (+ coverage checks)
|
|
145
|
+
|
|
146
|
+
**RULE.** Populate AI-readiness metadata on every component you create. Agents
|
|
147
|
+
consume the semantic layer in priority order — **metrics first, then calculated
|
|
148
|
+
fields, then raw fields** — so a well-enriched metric set matters more to answer
|
|
149
|
+
quality than raw field coverage. The full checklist, description-quality guide,
|
|
150
|
+
and `businessPreferences` examples live in `ai-readiness.md`; this gate is the
|
|
151
|
+
enforceable summary.
|
|
152
|
+
|
|
153
|
+
**CHECK — metadata each created component must carry:**
|
|
154
|
+
|
|
155
|
+
- **`description`** on the model, each data object, each calculated dimension,
|
|
156
|
+
each calculated measure, and each metric. Missing descriptions are the top AI-
|
|
157
|
+
readiness defect. Custom objects/fields require a clear 1–2 sentence description
|
|
158
|
+
(business context, how it is used, any values with specific meaning); for
|
|
159
|
+
standard Salesforce objects/fields, only enhance the default — never contradict
|
|
160
|
+
it.
|
|
161
|
+
- **`primaryNameField`** on each `add_semantic_model_data_object` — the original
|
|
162
|
+
(pre-suffix) display-name column. **Known server bug:** the field registry is
|
|
163
|
+
empty at create time, so setting it at create fails with `"<field> does not
|
|
164
|
+
exist in <object> fields"` regardless of import mode. Document the missing
|
|
165
|
+
`primaryNameField` as a known gap.
|
|
166
|
+
- **`sentiment`** on directional calculated measures and metrics.
|
|
167
|
+
- **`businessPreferences`** on the model — free-text; set ≥1 statement of what
|
|
168
|
+
the model tracks and any domain terminology. **Read** with
|
|
169
|
+
`get_semantic_model_business_preferences` (`includeModelContent=false`).
|
|
170
|
+
**Write** with `update_semantic_model_business_preferences` (full replacement
|
|
171
|
+
of `# `-prefixed lines; empty string clears; omit the field to leave
|
|
172
|
+
unchanged; send only `businessPreferences`). Fallback: set at create or via
|
|
173
|
+
`update_semantic_model`. Details: `ai-readiness.md`.
|
|
174
|
+
- **`agentEnabled: true`** on the model — gates whether AI agents can use it.
|
|
175
|
+
`create_semantic_model` does **not** expose it (server default `false`); set it
|
|
176
|
+
via an immediate `update_semantic_model` after creation.
|
|
177
|
+
- **Label / type / role accuracy:** object-name + field-label unambiguously
|
|
178
|
+
identify the field's role; date columns are `Date`/`DateTime` (not `Text`);
|
|
179
|
+
numeric columns are measures, categorical/text/date are dimensions; a numeric
|
|
180
|
+
identifier is a **dimension**, not a measure.
|
|
181
|
+
- **apiName permanence:** model/object/calc-field apiNames cannot be edited after
|
|
182
|
+
creation — choose them descriptively (`Gross_Margin_Pct`, not `Calc3`); the only
|
|
183
|
+
fix is delete-and-recreate.
|
|
184
|
+
- **Ambiguity discipline:** differentiate similar fields in name, description, and
|
|
185
|
+
purpose; never copy-paste descriptions. Watch synonyms (two names, one concept →
|
|
186
|
+
remove one; when asked to create two fields with the same/equivalent formula,
|
|
187
|
+
treat as a synonym — declare one canonical, decline the other or ask) and
|
|
188
|
+
homonyms (one column serving two business dates → two calc dimensions with
|
|
189
|
+
distinct labels + explicit descriptions). Omit niche/redundant fields rather
|
|
190
|
+
than leaving them undescribed.
|
|
191
|
+
- Bulk-imported fields (`shouldIncludeAllFields: true`) carry no descriptions and
|
|
192
|
+
get unpredictable apiName suffixes — do **not** use this for model-level bind
|
|
193
|
+
(deprecated). Prefer **nested explicit fields** on
|
|
194
|
+
`create_semantic_model` / `add_semantic_model_data_object`
|
|
195
|
+
(`shouldIncludeAllFields: false`) so descriptions, types, and clean apiNames
|
|
196
|
+
are set at creation. Include join-key fields in those arrays. Reserve
|
|
197
|
+
`add_semantic_model_dimension` / `_measure` for adding a single extra field
|
|
198
|
+
to an already-bound object. Backfill missing descriptions via sparse
|
|
199
|
+
`update_semantic_model_dimension` / `_measure` — these are sparse
|
|
200
|
+
(unlike metric / calc-measure / relationship, which are full PUT). **`isVisible`
|
|
201
|
+
is NOT preserved:** omitting it silently resets a hidden field to
|
|
202
|
+
`isVisible: true`. Always `list_*` first and echo the current `isVisible` and
|
|
203
|
+
`dataObjectFieldName` (omitting `dataObjectFieldName` sends null and
|
|
204
|
+
`SEMANTIC_FIELD_NOT_VALID`). Do not send description-only. Shape:
|
|
205
|
+
`sdm-tool-reference.md`.
|
|
206
|
+
|
|
207
|
+
**CHECK — pre-creation coverage checks (before adding enrichment):**
|
|
208
|
+
|
|
209
|
+
- **Calculated dimension:** MUST call `list_semantic_model_calculated_dimensions`
|
|
210
|
+
first, to check for overlapping coverage of the same source field.
|
|
211
|
+
- **Calculated measure:** MUST call **both**
|
|
212
|
+
`list_semantic_model_calculated_measures` **and**
|
|
213
|
+
`list_semantic_model_metrics` first. Use `aggregationType: "UserAgg"` (not
|
|
214
|
+
`Auto`) when the expression already aggregates (`AVG`, `SUM/COUNT`, `COUNTD`).
|
|
215
|
+
- **Metric (decision #3 — parity resolution):** MUST call
|
|
216
|
+
`list_semantic_model_metrics` first to check that an equivalent metric does not
|
|
217
|
+
already exist (metrics had no pre-creation coverage check historically; this
|
|
218
|
+
gate adds one for parity with calc dimensions/measures). A metric additionally
|
|
219
|
+
requires `insightsSettings.identifyingDimension`, a concrete `aggregationType`
|
|
220
|
+
(**never `Auto`** — rejected: *"The aggregation type (Auto) is not allowed for
|
|
221
|
+
metric aggregation"*), counting via a **numeric field + `Count`** (not a
|
|
222
|
+
dimension/Primary Key — pointing `measurementReference` at a Primary Key is rejected), and a
|
|
223
|
+
**full-PUT `insightsSettings`** on every `update_semantic_model_metric` (it is a
|
|
224
|
+
full PUT; omitting `insightsSettings` nulls it and crashes the metric UI).
|
|
225
|
+
|
|
226
|
+
**ON FAILURE.** Do not declare a model AI-ready on metadata completeness alone —
|
|
227
|
+
always recommend the Semantic Model AI Optimization similarity scan (Semantic
|
|
228
|
+
Model Builder UI) before handoff; `modelHealth: Low` flags ambiguous components.
|
|
229
|
+
Add the missing metadata / run the missing coverage check before proceeding.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## G6 — Data-understanding profiling
|
|
234
|
+
|
|
235
|
+
**RULE.** Understand the data before you model it — there is no natural-language
|
|
236
|
+
query layer here to infer meaning for you. This applies even over an **already-
|
|
237
|
+
built** model you do not yet understand; it does NOT drag in Step 0 ingest or the
|
|
238
|
+
large-flat-file protocol on a pre-existing model.
|
|
239
|
+
|
|
240
|
+
**CHECK.** Profile the five things before choosing calc fields, metrics, or charts
|
|
241
|
+
(`data-understanding.md:33-41`): **grain, field roles, cardinality, additivity,
|
|
242
|
+
date roles.** For a large/wide/cryptic flat file, first run the infer-first
|
|
243
|
+
variant (`infer_object_schema` without loading the file into context, decode the
|
|
244
|
+
column-naming grammar, elicit the genuinely ambiguous columns, then verify one
|
|
245
|
+
known number with `run_query` after ingest — `large-flat-file-handling.md`).
|
|
246
|
+
|
|
247
|
+
**ON FAILURE.** Without this, you ship the populated-but-confidently-wrong result
|
|
248
|
+
that passes a "does it return rows?" check: an ID summed as a measure, a snapshot
|
|
249
|
+
inflated by its date count, a metric anchored on a load/system timestamp instead
|
|
250
|
+
of a business-event date, a 100×-off measure that profiled perfectly. Do not
|
|
251
|
+
model or metricize until grain + additivity + the business-event date are known.
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## G7 — Query-returns-real-data validation
|
|
256
|
+
|
|
257
|
+
**RULE.** A query that returns rows is the proof the model actually works. A join
|
|
258
|
+
that matches ~0 rows is as broken as no join at all.
|
|
259
|
+
|
|
260
|
+
**CHECK.** Run `run_semantic_query` (snake_case proto body — see G-note) and
|
|
261
|
+
confirm real rows come back: before charting (Step 10), after adding a
|
|
262
|
+
relationship (validate the join key with a real JOIN row-count), and at model
|
|
263
|
+
validation (Step 7). For a dashboard, the widget's underlying query must return
|
|
264
|
+
real rows first (transitive: a dashboard is only as valid as its widgets).
|
|
265
|
+
|
|
266
|
+
**ON FAILURE.** If the query returns empty (or a join matches ~0 rows), do NOT
|
|
267
|
+
build the viz/dashboard — STOP, treat the join/source as broken, and fix or
|
|
268
|
+
surface it.
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## G8 — Narrative-design-first (decision #1 — scoped)
|
|
273
|
+
|
|
274
|
+
**RULE.** Design the analytical story before dropping charts.
|
|
275
|
+
(`dashboard-design-principles.md:41-56`.)
|
|
276
|
+
|
|
277
|
+
- **Dashboards (full narrative — REQUIRED):** order the story KPIs → trends →
|
|
278
|
+
breakdowns → correlations; KPIs top/left on the F/Z eye-path; business-friendly
|
|
279
|
+
labels; chart-type diversity. This is MANDATORY for any dashboard build.
|
|
280
|
+
- **Single standalone viz (light "chart analytical intent" variant — decision
|
|
281
|
+
#1):** for one chart with no dashboard, the full dashboard narrative is NOT
|
|
282
|
+
required. State the chart's analytical intent — what question this one chart
|
|
283
|
+
answers and why this chart type fits the field roles (trend/breakdown/
|
|
284
|
+
correlation/KPI) — then create it. Do NOT invent a dashboard around a single-viz
|
|
285
|
+
ask.
|
|
286
|
+
|
|
287
|
+
**CHECK.** Before the first `create_visualization`: if the ask is a dashboard,
|
|
288
|
+
confirm the full narrative order; if the ask is a single chart, confirm a stated
|
|
289
|
+
chart intent. Match chart type to what each field is showing — do not default
|
|
290
|
+
every widget to a bar chart.
|
|
291
|
+
|
|
292
|
+
**ON FAILURE.** If you are about to jump straight into chart calls with no stated
|
|
293
|
+
intent (single viz) or no narrative (dashboard), STOP and design first.
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## G-notes (shapes cited by the gates, kept here so guides don't re-type them)
|
|
298
|
+
|
|
299
|
+
- **`run_semantic_query` body is snake_case proto** (`table_field`, `grouping`,
|
|
300
|
+
`semantic_aggregation_method`) — REST-gateway camelCase examples fail. Prefer an
|
|
301
|
+
existing metric / calc measure over reconstructing an aggregation inline. Full
|
|
302
|
+
shape: `semantic-query-and-enrichment.md`.
|
|
303
|
+
- **Ingest mapping:** file-upload DLOs **and** DMOs use `category: "Other"`;
|
|
304
|
+
DLO→DMO mapping field dev names carry a literal `__c` on **both** sides.
|
|
305
|
+
DLO Active → DMO Ready still wait on status. Mapping **query** readiness is
|
|
306
|
+
`run_query` against `<dmo>__dlm` (`42P01` keep polling; `COUNT = 0` is READY).
|
|
307
|
+
`get_dlo_to_dmo_mapping_status` `ACTIVE` is metadata only. Connection ingest
|
|
308
|
+
(Snowflake / …) is the same tail after `list_connections` —
|
|
309
|
+
`ingest-and-metric-gotchas.md` §C. Full chain: `ingest-and-metric-gotchas.md`
|
|
310
|
+
§A.
|
|
311
|
+
- **Dashboard widget editing** goes through `edit_dashboard`'s atomic
|
|
312
|
+
`upsert_*_widget` + `place_widget_on_page` batch — the only supported path.
|
|
313
|
+
Stored text labels must not contain `&` (HTML-encodes to `&`). Full
|
|
314
|
+
mechanics: `edit-dashboard.md`.
|
|
315
|
+
- **Dashboard save never auto-persists** — the objective-9 analog for
|
|
316
|
+
dashboards. `edit_dashboard` stages an unsaved draft by default (top-level
|
|
317
|
+
`autosave`); a `save_dashboard` op persists it (standalone, or after other
|
|
318
|
+
mutations in the same batch), but only call `save_dashboard` on the user's
|
|
319
|
+
explicit confirmation given *after* they've
|
|
320
|
+
seen the draft — even if the original request already said "save it" in the
|
|
321
|
+
same message as the edit. Same rule, same rationale, as `edit_visualization`
|
|
322
|
+
→ `update_visualization` (objective 9, `edit-visualization.md` §8).
|