diff --git a/gatsby-node.js b/gatsby-node.js index 98a9cf3a9..4691bca91 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -78,6 +78,13 @@ exports.onPostBuild = async ({ graphql, reporter }) => { node { document { title } pageAttributes { pageid } + fields { markdownBody } + parent { + ... on File { + sourceInstanceName + relativePath + } + } } } } @@ -85,17 +92,45 @@ exports.onPostBuild = async ({ graphql, reporter }) => { `); if (result.errors) { - reporter.warn(`llms.txt generation: GraphQL errors — ${JSON.stringify(result.errors)}`); + reporter.warn(`Build-time generation: GraphQL errors — ${JSON.stringify(result.errors)}`); return; } - const pageMap = {}; + // pageData keyed by pageid: { title, docPath } + // docPath is the URL-path segment (e.g. '/getting-started', '/tutorials/intro') + // derived from getDocLinkFromEdge so tutorials with subdirectories resolve correctly. + const pageData = {}; + let mdCount = 0; + result.data.allAsciidoc.edges.forEach(({ node }) => { const pageid = node.pageAttributes?.pageid; const title = node.document?.title; - if (pageid && title) pageMap[pageid] = title; + const markdownBody = node.fields?.markdownBody; + const relativePath = node.parent?.relativePath || ''; + // Auto-generated per-symbol SDK reference pages (scripts/Converter/index.ts) — + // represented in llms.txt by the single curated VisualEmbedSdk entry, not individually. + const isTypedocGenerated = relativePath.startsWith('generated/typedoc/'); + + if (!pageid || pageid.startsWith('nav-')) return; + + const docPath = getDocLinkFromEdge({ node }); // e.g. '/getting-started' or '/tutorials/category/page' + if (title) pageData[pageid] = { title, docPath, isTypedocGenerated }; + + // Write static .md file — serves at /docs.md for agent crawlers + if (markdownBody) { + const header = `# ${title ?? pageid}\n\n> For the complete documentation index, see [llms.txt](${SITE_URL}/llms.txt)\n\nSource: ${SITE_URL}${docPath}\n\n`; + fsExtra.outputFileSync( + `${__dirname}/public${docPath}.md`, + header + markdownBody, + ); + mdCount++; + } }); + reporter.info(`[md-gen] Wrote ${mdCount} .md files`); + + // Generate llms.txt — curated sections first, then any remaining pages + const coveredIds = new Set(); const lines = [ '# ThoughtSpot Developer Documentation', '', @@ -104,11 +139,29 @@ exports.onPostBuild = async ({ graphql, reporter }) => { ]; for (const section of LLMS_SECTIONS) { - lines.push(`## ${section.label}`); + const sectionLines = []; for (const pageId of section.pageIds) { - const title = pageMap[pageId]; - if (title) lines.push(`- [${title}](${SITE_URL}/${pageId})`); + const data = pageData[pageId]; + if (data) { + sectionLines.push(`- [${data.title}](${SITE_URL}${data.docPath}.md)`); + coveredIds.add(pageId); + } + } + if (sectionLines.length) { + lines.push(`## ${section.label}`); + lines.push(...sectionLines); + lines.push(''); } + } + + // Add pages that exist as Asciidoc nodes but aren't in any LLMS_SECTIONS entry. + // Excludes typedoc-generated pages — those are covered by the curated VisualEmbedSdk entry. + const uncovered = Object.entries(pageData).filter( + ([id, data]) => !coveredIds.has(id) && !data.isTypedocGenerated, + ); + if (uncovered.length) { + lines.push('## Additional documentation'); + uncovered.forEach(([, { title, docPath }]) => lines.push(`- [${title}](${SITE_URL}${docPath}.md)`)); lines.push(''); } @@ -116,9 +169,9 @@ exports.onPostBuild = async ({ graphql, reporter }) => { `${__dirname}/public/llms.txt`, lines.join('\n'), ); - reporter.info(`llms.txt generated with ${Object.keys(pageMap).length} pages`); + reporter.info(`llms.txt: ${coveredIds.size} curated + ${uncovered.length} additional = ${coveredIds.size + uncovered.length} total pages`); } catch (err) { - reporter.warn(`llms.txt generation failed: ${err.message}`); + reporter.warn(`Build-time generation failed: ${err.message}`); } }; exports.createPages = async function ({ actions, graphql }) { diff --git a/gatsby-ssr.js b/gatsby-ssr.js new file mode 100644 index 000000000..429fb8c9e --- /dev/null +++ b/gatsby-ssr.js @@ -0,0 +1,36 @@ +const React = require('react'); +const { SITE_URL } = require('./src/configs/doc-configs'); + +exports.onRenderBody = ({ setHeadComponents, setPreBodyComponents }) => { + setHeadComponents([ + React.createElement('link', { + key: 'llms-txt', + rel: 'llms-txt', + href: `${SITE_URL}/llms.txt`, + }), + ]); + + // Visually-hidden body element — picked up by agent crawlers that parse the DOM + // but ignore link tags (Mintlify llms-txt-directive-html check). + setPreBodyComponents([ + React.createElement( + 'div', + { + key: 'llms-txt-directive', + style: { + position: 'absolute', + width: '1px', + height: '1px', + overflow: 'hidden', + clip: 'rect(0,0,0,0)', + whiteSpace: 'nowrap', + }, + }, + React.createElement( + 'a', + { href: `${SITE_URL}/llms.txt` }, + 'LLMs.txt: Complete documentation index for AI agents', + ), + ), + ]); +}; diff --git a/modules/ROOT/pages/common/nav-embedding.adoc b/modules/ROOT/pages/common/nav-embedding.adoc index 004467551..4f5f8a246 100644 --- a/modules/ROOT/pages/common/nav-embedding.adoc +++ b/modules/ROOT/pages/common/nav-embedding.adoc @@ -173,10 +173,6 @@ include::generated/typedoc/CustomSideNav.adoc[] [.sidebar-title] Additional resources -* link:{{navprefix}}/embed-ts[About ThoughtSpot embedding] -* link:{{navprefix}}/get-started-tse[Embed licenses] -* link:{{navprefix}}/license-feature-matrix[Feature matrix] * link:{{navprefix}}/faqs[FAQs] -* link:{{navprefix}}/code-samples[Code samples] * link:https://codesandbox.io/s/big-tse-react-demo-i4g9xi[React CodeSandbox, window=_blank] -* link:https://codesandbox.io/s/graphqlcookieembed-wf4fk9?file=/src/App.js:418-426[GraphQL CodeSandbox, window=_blank] +* link:https://github.com/thoughtspot/developer-examples[Developer examples, window=_blank] diff --git a/modules/ROOT/pages/common/nav-in-product-help.adoc b/modules/ROOT/pages/common/nav-in-product-help.adoc new file mode 100644 index 000000000..cf7312ff9 --- /dev/null +++ b/modules/ROOT/pages/common/nav-in-product-help.adoc @@ -0,0 +1,308 @@ + +:page-pageid: nav-in-product-help +:page-description: In-product navigation + +[navSection] + +[.sidebar-title] +Release notes and changelogs + +* link:{{navprefix}}/whats-new[What's new] +* Changelog +** link:{{navprefix}}/embed-sdk-changelog[Visual Embed SDK changelog] +** link:{{navprefix}}/mobile-sdk-changelog[Mobile Embed SDK changelog] +** link:{{navprefix}}/rest-v2-changelog[REST API v2 changelog] +* link:{{navprefix}}/deprecated-features[Deprecation announcements] + +[.sidebar-title] +Live Playgrounds + +* +++Visual Embed Playground+++ +** link:{{navprefix}}/dev-playground[How to use] +* link:{{navprefix}}/restV2-playground?apiResourceId=http%2Fgetting-started%2Fintroduction[REST API v2 Playground] +** link:{{navprefix}}/rest-playground[How to use] +* +++Theme Builder+++ +** link:{{navprefix}}/theme-builder-doc[How to use] + +[.sidebar-title] +Embed ThoughtSpot in a web app + +* link:{{navprefix}}/getting-started[Embed with Visual Embed SDK] +* link:{{navprefix}}/tsembed[Quickstart guide] +* link:{{navprefix}}/embed-ai-search-analytics[Embed AI Search and Analytics] +** link:{{navprefix}}/embed-spotter[Embed Spotter experience] +** link:{{navprefix}}/embed-spotter-agent[Embed Spotter Agent] +* link:{{navprefix}}/embed-liveboard[Embed Analytics] +** link:{{navprefix}}/embed-liveboard[Embed a Liveboard] +** link:{{navprefix}}/spotterViz-agent[SpotterViz AI agent in Liveboards] +** link:{{navprefix}}/embed-a-viz[Embed a visualization] +* link:{{navprefix}}/full-embed[Embed full application] +** link:{{navprefix}}/full-app-customize[Customize your embed] +** link:{{navprefix}}/customize-nav-controls[Customize navigation panels] +** link:{{navprefix}}/set-default-page[Customize default page and navigation path] +** link:{{navprefix}}/customize-homepage-experience[Customize home page experience] +* Embed token-based Search +** link:{{navprefix}}/search-embed[Embed Search] +** link:{{navprefix}}/embed-searchbar[Embed search bar] +** link:{{navprefix}}/visualization-overrides[Visualization overrides] +* link:{{navprefix}}/react-app-embed[Embed with React components] + +[.sidebar-title] +Embed ThoughtSpot in a mobile app + +* link:{{navprefix}}/mobile-embed[Overview] +* link:{{navprefix}}/embed-ts-mobile-react-native[React Native SDK] +* link:{{navprefix}}/embed-ts-flutter[Flutter embed SDK] +* link:{{navprefix}}/embed-ts-swift[Swift Embed SDK] +* link:{{navprefix}}/embed-ts-android[Android Embed SDK] + +[.sidebar-title] +Embed without SDK + +** link:{{navprefix}}/embed-without-sdk[Embed without SDK] +** link:{{navprefix}}/custom-viz-rest-api[Create a custom visualization] + +[.sidebar-title] +Authentication and data security + +* link:{{navprefix}}/embed-auth[Authentication] +** link:{{navprefix}}/trusted-auth[Trusted authentication] +*** link:{{navprefix}}/trusted-auth-secret-key[Secret key management] +*** link:{{navprefix}}/trusted-auth-sdk[Front-end trusted authentication integration] +*** link:{{navprefix}}/trusted-auth-token-request-service[Token request service] +*** link:{{navprefix}}/trusted-auth-troubleshoot[Troubleshoot trusted authentication] +** link:{{navprefix}}/saml-sso[SAML SSO authentication] +** link:{{navprefix}}/oidc-auth[OpenID Connect authentication] +** link:{{navprefix}}/just-in-time-provisioning[Just-in-time provisioning] +* link:{{navprefix}}/security-settings[Security settings] + +* link:{{navprefix}}/embed-object-access[Authorization] +** link:{{navprefix}}/access-control-sharing[Access control and sharing] +** link:{{navprefix}}/privileges-and-roles[Privileges and Roles] +** link:{{navprefix}}/data-security[Data security] +*** link:{{navprefix}}/rls-rules[RLS Rules] +*** link:{{navprefix}}/abac-via-rls-variables[ABAC via RLS with variables] +*** link:{{navprefix}}/jwt-abac-migration-guide[ABAC JWT migration guide] +**** link:{{navprefix}}/jwt-filter-parameters-rules-migration-guide[JWT ABAC with filter rules -> ABAC via RLS] +**** link:{{navprefix}}/jwt-abac-beta-migration-guide[JWT ABAC beta implementation -> ABAC via RLS] +*** link:{{navprefix}}/abac-user-parameters[ABAC via JWT with filter rules and parameters] +* link:{{navprefix}}/selective-user-access[User access] +* link:{{navprefix}}/troubleshoot-errors[Troubleshoot errors] + +[.sidebar-title] +Customize and integrate + +* link:{{navprefix}}/style-customization[Customize UI layout and styles] +** link:{{navprefix}}/customize-style[Customize basic styles] +** link:{{navprefix}}/custom-css[CSS customization framework] +** link:{{navprefix}}/theme-builder-doc[Theme builder] +** link:{{navprefix}}/customize-icons[Customize icons] +** link:{{navprefix}}/customize-text[Customize text strings] +** link:{{navprefix}}/css-variables-reference[CSS variables reference] + +* link:{{navprefix}}/filters-overview[Filters types and application layers] +** link:{{navprefix}}/runtime-overrides[Runtime overrides] +** link:{{navprefix}}/runtime-filters[Runtime filters] +** link:{{navprefix}}/runtime-params[Runtime Parameters] +* link:{{navprefix}}/action-config[Customize menus] +** link:{{navprefix}}/actions[Action IDs in the SDK] +* link:{{navprefix}}/events-app-integration[Events and app interactions] +** link:{{navprefix}}/embed-events[Using embed events] +** link:{{navprefix}}/host-events[Using host events] +** link:{{navprefix}}/context-aware-event-routing[Context-based execution of host events] +** link:{{navprefix}}/hostEventsV2-migration[Migrating from Host Event v1 to Host Events v2 framework] +** link:{{navprefix}}/handling-embed-errors[Handling embed errors] +** link:{{navprefix}}/api-search-intercept[API intercept and data fetch requests] + +* link:{{navprefix}}/custom-action-intro[Custom actions] +** link:{{navprefix}}/customize-actions[Custom actions through the UI] +*** link:{{navprefix}}/custom-action-url[URL actions] +*** link:{{navprefix}}/custom-action-callback[Callback actions] +*** link:{{navprefix}}/edit-custom-action[Set the position of a custom action] +*** link:{{navprefix}}/add-action-viz[Add a local action to a visualization] +*** link:{{navprefix}}/add-action-worksheet[Add a local action to a model] +** link:{{navprefix}}/code-based-custom-action[Code based custom actions] +** link:{{navprefix}}/custom-action-payload[Callback response payload] + +* link:{{navprefix}}/customize-links[Customize links] +* link:{{navprefix}}/set-locale[Customize locale] +* link:{{navprefix}}/custom-domain-config[Custom domain configuration] +* link:{{navprefix}}/customize-emails[Customize onboarding settings] +* link:{{navprefix}}/customize-email-apis[Customize email template] +* link:{{navprefix}}/in-app-navigation[Create dynamic menus and navigation] +* link:{{navprefix}}/best-practices[Performance optimization] +** link:{{navprefix}}/best-practices[Best practices] +** link:{{navprefix}}/prerender[Prerender components] +** link:{{navprefix}}/lazy-load-fullHeight[Full height and lazy loading options] +** link:{{navprefix}}/prefetch[Prefetch static resources] +* link:{{navprefix}}/troubleshoot-errors[Troubleshoot errors] + +[.sidebar-title] +Visual Embed SDK reference guide + +* link:{{navprefix}}/VisualEmbedSdk[Visual Embed SDK Reference] +include::generated/typedoc/CustomSideNav.adoc[] +** Custom styles +*** [.typedoc-Interface]#link:{{navprefix}}/Interface_CustomStyles[CustomStyles]# +*** [.typedoc-Interface]#link:{{navprefix}}/Interface_CustomisationsInterface[CustomisationsInterface]# +*** [.typedoc-Interface]#link:{{navprefix}}/Interface_customCssInterface[customCssInterface]# +*** [.typedoc-Interface]#link:{{navprefix}}/Interface_CustomCssVariables[customCssVariables]# +** Runtime filters +*** [.typedoc-Interface]#link:{{navprefix}}/Interface_RuntimeFilter[RuntimeFilter]# +*** [.typedoc-Enumeration]#link:{{navprefix}}/Enumeration_RuntimeFilterOp[RuntimeFilterOp]# +** Others +*** [.typedoc-Enumeration]#link:{{navprefix}}/Enumeration_Action[Action]# +*** [.typedoc-Enumeration]#link:{{navprefix}}/Enumeration_ContextMenuTriggerOptions[ContextMenuTriggerOptions]# +*** [.typedoc-Enumeration]#link:{{navprefix}}/Enumeration_DataSourceVisualMode[DataSourceVisualMode]# +*** [.typedoc-Enumeration]#link:{{navprefix}}/Enumeration_Page[Page]# +*** [.typedoc-Enumeration]#link:{{navprefix}}/Enumeration_PrefetchFeatures[PrefetchFeatures]# +*** [.typedoc-Function]#link:{{navprefix}}/Function_executeTML[executeTML]# +*** [.typedoc-Function]#link:{{navprefix}}/Function_exportTML[exportTML]# + + +[.sidebar-title] +Multi-tenancy + +* link:{{navprefix}}/multi-tenancy[Overview] +* link:{{navprefix}}/orgs[Multi-tenancy with Orgs] +** link:{{navprefix}}/orgs-api-op[Org administration] +** link:{{navprefix}}/multitenancy-within-an-org[Multi-tenancy within an Org] +** link:{{navprefix}}/single-tenant-data-models[Single-tenant data models with Orgs] +* link:{{navprefix}}/tse-cluster[Cluster maintenance and upgrade] + +[.sidebar-title] +Webhooks + +* link:{{navprefix}}/webhooks-overview[Overview] +* link:{{navprefix}}/webhooks-ui[Webhooks UI] +* link:{{navprefix}}/webhooks-comm-channel[Webhook communication channels] +* link:{{navprefix}}/webhooks-lb-schedule[Webhook connection for Liveboard scheduled events] +* link:{{navprefix}}/webhooks-s3-integration[AWS S3 storage integration for webhook delivery] +* link:{{navprefix}}/webhooks-gcs-storage[GCS storage integration for webhook delivery] +* link:{{navprefix}}/webhooks-lb-payload[Webhook response payload] +* link:{{navprefix}}/webhooks-kpi[Webhook connection for KPI alerts] + +[.sidebar-title] +Integration with external tools + +** link:{{navprefix}}/external-tool-script-integration[External tools and scripts] +** link:{{navprefix}}/pendo-integration[Pendo integration with embed] +** link:{{navprefix}}/sf-integration[Integration with Salesforce] +** link:{{navprefix}}/vercel-integration[Vercel integration] + +[.sidebar-title] +Build and deploy + +** link:{{navprefix}}/thoughtspot-objects[ThoughtSpot objects] +** link:{{navprefix}}/timezone-aware-filtering[Timezone-aware keywords and filters] +** link:{{navprefix}}/variables[Variables] +** link:{{navprefix}}/parameterize-metadata[Parameterize metadata] +* link:{{navprefix}}/development-and-deployment[Development and deployment] +** link:{{navprefix}}/deploy-with-tml-apis[Deploy with TML APIs] +*** link:{{navprefix}}/git-provider-integration[Git provider integration] +*** link:{{navprefix}}/modify-tml[TML modification] +* link:{{navprefix}}/publish-data-overview[Publish content to Orgs] +** link:{{navprefix}}/publish-to-orgs[Publish objects to Orgs] +* link:{{navprefix}}/git-integration[Deploy with GitHub APIs (legacy)] +** link:{{navprefix}}/git-configuration[Configure GitHub integration] +** link:{{navprefix}}/git-api[GitHub REST APIs] +** link:{{navprefix}}/guid-mapping[GUID mapping] + +[.sidebar-title] +REST APIs + +* link:{{navprefix}}/rest-apis[Overview] +* link:{{navprefix}}/rest-apiv2-getstarted[Get started] +* link:{{navprefix}}/api-authv2[REST API v2.0 authentication] +* link:{{navprefix}}/rest-apiv2-reference[REST API v2.0 Reference] +** link:{{navprefix}}/api-user-management[Users and group privileges] +** link:{{navprefix}}/rbac[Role-based access control] +** link:{{navprefix}}/rest-apiv2-search[Search API endpoints] +*** link:{{navprefix}}/rest-apiv2-users-search[Search users] +*** link:{{navprefix}}/rest-apiv2-groups-search[Search groups] +*** link:{{navprefix}}/rest-apiv2-metadata-search[Search metadata] +** link:{{navprefix}}/fetch-data-and-report-apis[Data and Report APIs] +** link:{{navprefix}}/spotter-api[Spotter APIs] +*** link:{{navprefix}}/spotter-agent-apis[AI APIs (Spotter Agent and Spotter 3)] +*** link:{{navprefix}}/spotter-agent-instructions[Spotter AI agent instructions] +*** link:{{navprefix}}/spotter-agent-conversation-mgmt-apis[APIs for managing saved conversations] +*** link:{{navprefix}}/spotter-apis-classic[AI APIs (Spotter Classic) ^BETA^] +*** link:{{navprefix}}/spotter-nl-instructions[Data model instructions APIs ^BETA^] +** link:{{navprefix}}/style-customization-apis[Style customization APIs] +** link:{{navprefix}}/audit-logs[Audit logs] +** link:{{navprefix}}/tml[TML] +** link:{{navprefix}}/collections[Collections ^BETA^] +** link:{{navprefix}}/connections[Connections] +** link:{{navprefix}}/connection-config[Connection configuration] +** link:{{navprefix}}/runtime-sort[Runtime sorting] +* link:{{navprefix}}/manual-translation-api[Manual translations] +* link:{{navprefix}}/webhooks-rest-api[Webhook APIs] + +[.sidebar-title] +REST API SDK + +* link:{{navprefix}}/rest-api-sdk[Overview] +* link:{{navprefix}}/rest-api-sdk-typescript[TypeScript SDK] +* link:{{navprefix}}/rest-api-sdk-java[Java SDK] +* link:{{navprefix}}/rest-apiv2-js[REST API v2.0 in JavaScript] + +[.sidebar-title] +REST API v1 (DEPRECATED) + +* link:{{navprefix}}/rest-api-getstarted[Get started] +* link:{{navprefix}}/api-auth-session[REST API v1 authentication] +* link:{{navprefix}}/catalog-and-audit[Catalog and audit content] +* link:{{navprefix}}/rest-api-pagination[Paginate API response] +* link:{{navprefix}}/rest-api-reference[REST API v1 Reference] +* link:{{navprefix}}/rest-v1-changelog[REST API v1 changelog] +* link:{{navprefix}}/v1v2-comparison[REST v1 and v2.0 comparison] + + +[.sidebar-title] +SpotterCode + +* link:{{navprefix}}/SpotterCode[SpotterCode for IDEs] +* link:{{navprefix}}/integrate-SpotterCode[Integrating SpotterCode] +* link:{{navprefix}}/spottercode-prompting-guide[SpotterCode prompting guide] + +[.sidebar-title] +Tutorials + +* link:{{navprefix}}/tutorials/tutorials-overview[Embedding tutorials] +** link:{{navprefix}}/tutorials/tse-fundamentals/intro[Embedding Fundamentals] +*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-01[01 - Overview] +*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-02[02 - Set up for course] +*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-03[03 - Security setup] +*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-04[04 - Start coding] +*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-05[05 - Embed Search] +*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-06[06 - Embed Natural Language Search] +*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-07[07 - Embed Liveboard] +*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-08[08 - Embed Visualization] +*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-09[09 - Embed full application] +*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-10[10 - Style embedded app] +*** link:{{navprefix}}/tutorials/tse-fundamentals/lesson-11[11 - Course summary] +*** link:{{navprefix}}/tutorials/style-customization/tutorial[Style customization] +** link:{{navprefix}}/tutorials/react-components/intro[React components] +*** link:{{navprefix}}/tutorials/react-components/lesson-01[01 - Initialize Visual Embed SDK] +*** link:{{navprefix}}/tutorials/react-components/lesson-02[02 - ThoughtSpot component pages] +*** link:{{navprefix}}/tutorials/react-components/lesson-03[03 - Menus and navigation elements] +*** link:{{navprefix}}/tutorials/react-components/lesson-04[04 - Event handling] +** link:{{navprefix}}/tutorials/spotter/integrate-into-chatbot[Integrate Spotter into your Chatbot] + +* link:{{navprefix}}/tutorials/rest-api/intro[REST API Tutorials] +** link:{{navprefix}}/tutorials/rest-api/lesson-01[01 - REST API overview] +** link:{{navprefix}}/tutorials/rest-api/lesson-02[02 - Simple Python implementation] +** link:{{navprefix}}/tutorials/rest-api/lesson-03[03 - Complex REST API workflows] + + +[.sidebar-title] +Additional resources + +* link:{{navprefix}}/embed-ts[About ThoughtSpot embedding] +* link:{{navprefix}}/faqs[FAQs] +* link:https://codesandbox.io/s/big-tse-react-demo-i4g9xi[React CodeSandbox, window=_blank] +* link:https://community.thoughtspot.com/customers/s/[Community, window=_blank] +* link:https://training.thoughtspot.com/page/developer[Training resources, window=_blank] +* link:https://docs.thoughtspot.com[Product Documentation, window=_blank] +* link:https://github.com/thoughtspot/developer-examples[Developer examples, window=_blank] + diff --git a/modules/ROOT/pages/common/nav-rest-api.adoc b/modules/ROOT/pages/common/nav-rest-api.adoc index 04378ff93..62dc5391c 100644 --- a/modules/ROOT/pages/common/nav-rest-api.adoc +++ b/modules/ROOT/pages/common/nav-rest-api.adoc @@ -22,8 +22,10 @@ REST APIs ** link:{{navprefix}}/fetch-data-and-report-apis[Data and Report APIs] ** link:{{navprefix}}/spotter-api[Spotter APIs] *** link:{{navprefix}}/spotter-agent-apis[AI APIs (Spotter Agent and Spotter 3)] +*** link:{{navprefix}}/spotter-agent-instructions[Spotter AI agent instructions] +*** link:{{navprefix}}/spotter-agent-conversation-mgmt-apis[APIs for managing saved conversations] *** link:{{navprefix}}/spotter-apis-classic[AI APIs (Spotter Classic) ^BETA^] -*** link:{{navprefix}}/spotter-coaching-apis[Spotter coaching APIs ^BETA^] +*** link:{{navprefix}}/spotter-nl-instructions[Data model instructions APIs ^BETA^] ** link:{{navprefix}}/style-customization-apis[Style customization APIs] ** link:{{navprefix}}/audit-logs[Audit logs] ** link:{{navprefix}}/tml[TML] @@ -31,28 +33,8 @@ REST APIs ** link:{{navprefix}}/connections[Connections] ** link:{{navprefix}}/connection-config[Connection configuration] ** link:{{navprefix}}/runtime-sort[Runtime sorting] -* link:{{navprefix}}/api-user-management[Users and group privileges] -* link:{{navprefix}}/rbac[Role-based access control] -* link:{{navprefix}}/rest-apiv2-search[Search API endpoints] -** link:{{navprefix}}/rest-apiv2-users-search[Search users] -** link:{{navprefix}}/rest-apiv2-groups-search[Search groups] -** link:{{navprefix}}/rest-apiv2-metadata-search[Search metadata] -* link:{{navprefix}}/fetch-data-and-report-apis[Data and Report APIs] -* link:{{navprefix}}/spotter-api[Spotter APIs] -** link:{{navprefix}}/spotter-agent-apis[AI APIs (Spotter Agent and Spotter 3)] -** link:{{navprefix}}/spotter-agent-instructions[Spotter AI agent instructions] -** link:{{navprefix}}/spotter-agent-conversation-mgmt-apis[APIs for managing saved conversations] -** link:{{navprefix}}/spotter-apis-classic[AI APIs (Spotter Classic) ^BETA^] -** link:{{navprefix}}/spotter-nl-instructions[Spotter instructions APIs ^BETA^] -** link:{{navprefix}}/spotter-agent-instructions[Spotter instructions APIs ^BETA^] -* link:{{navprefix}}/audit-logs[Audit logs] -* link:{{navprefix}}/tml[TML] -* link:{{navprefix}}/collections[Collections ^BETA^] -* link:{{navprefix}}/connections[Connections] -* link:{{navprefix}}/connection-config[Connection configuration] -* link:{{navprefix}}/runtime-sort[Runtime sorting] -* link:{{navprefix}}/manual-translation-api[Manual translations] -* link:{{navprefix}}/webhooks-rest-api[Webhook APIs] +** link:{{navprefix}}/manual-translation-api[Manual translations] +** link:{{navprefix}}/webhooks-rest-api[Webhook APIs] [.sidebar-title] @@ -79,28 +61,14 @@ REST API v1 (DEPRECATED) * link:{{navprefix}}/catalog-and-audit[Catalog and audit content] * link:{{navprefix}}/rest-api-pagination[Paginate API response] * link:{{navprefix}}/rest-api-reference[REST API v1 Reference] -** link:{{navprefix}}/orgs-api[Orgs API] -** link:{{navprefix}}/user-api[User API] -** link:{{navprefix}}/group-api[Group API] -** link:{{navprefix}}/role-api[Role API] -** link:{{navprefix}}/session-api[Session API] -** link:{{navprefix}}/connections-api[Data connection API] -** link:{{navprefix}}/metadata-api[Metadata API] -** link:{{navprefix}}/admin-api[Admin API] -** link:{{navprefix}}/tml-api[TML API] -** link:{{navprefix}}/dependent-objects-api[Dependent objects API] -** link:{{navprefix}}/search-data-api[Search data API] -** link:{{navprefix}}/liveboard-data-api[Liveboard data API] -** link:{{navprefix}}/liveboard-export-api[Liveboard export API] -** link:{{navprefix}}/security-api[Security API] -** link:{{navprefix}}/logs-api[Audit logs API] -** link:{{navprefix}}/materialization-api[Materialization API] -** link:{{navprefix}}/database-api[Database API] -** link:{{navprefix}}/rest-v1-changelog[REST API v1 changelog] -** link:{{navprefix}}/v1v2-comparison[REST v1 and v2.0 comparison] - - -//** link:{{navprefix}}/graphql-guide[GraphQL API ^Beta^] +* link:{{navprefix}}/rest-v1-changelog[REST API v1 changelog] +* link:{{navprefix}}/v1v2-comparison[REST v1 and v2.0 comparison] + +[.sidebar-title] +Additional resources + +* link:{{navprefix}}/faqs[FAQs] +* link:https://github.com/thoughtspot/developer-examples[Developer examples, window=_blank] diff --git a/modules/ROOT/pages/common/nav.adoc b/modules/ROOT/pages/common/nav.adoc index a848131e2..141aada68 100644 --- a/modules/ROOT/pages/common/nav.adoc +++ b/modules/ROOT/pages/common/nav.adoc @@ -100,11 +100,7 @@ Additional resources * link:{{navprefix}}/faqs[FAQs] * link:https://codesandbox.io/s/big-tse-react-demo-i4g9xi[React CodeSandbox, window=_blank] -//** link:https://codesandbox.io/s/graphqlcookieembed-wf4fk9?file=/src/App.js:418-426[GraphQL CodeSandbox, window=_blank] - * link:https://community.thoughtspot.com/customers/s/[Community, window=_blank] * link:https://training.thoughtspot.com/page/developer[Training resources, window=_blank] * link:https://docs.thoughtspot.com[Product Documentation, window=_blank] -* link:https://developers.thoughtspot.com[ThoughtSpot Developers, window=_blank] -* Deprecated feature docs -** link:{{navprefix}}/abac-user-parameters-beta[ABAC via tokens (pre-10.4.0.cl) (Deprecated)] +* link:https://github.com/thoughtspot/developer-examples[Developer examples, window=_blank] diff --git a/modules/ROOT/pages/customize-links.adoc b/modules/ROOT/pages/customize-links.adoc index c4b185f00..310b00311 100644 --- a/modules/ROOT/pages/customize-links.adoc +++ b/modules/ROOT/pages/customize-links.adoc @@ -215,10 +215,9 @@ https://www.mysite.com/{path} == Override ThoughtSpot URLs -Link override settings allow embedded users to redirect native ThoughtSpot URLs to links within their host application. ThoughtSpot supports two Visual Embed SDK configurations for overriding links generated by ThoughtSpot. These settings work the same for multi-tenant ThoughtSpot embedded instances too. - -You can set the `linkOverride` to `true` in the Visual Embed SDK to override the link format of your embedded application pages and navigation links. Once enabled, all links opened in a new tab via the right-click menu will show host application URLs. +Link override settings allow embedded users to redirect native ThoughtSpot URLs to links within their host application. ThoughtSpot supports Visual Embed SDK configurations for overriding links generated by ThoughtSpot. These settings work the same for multi-tenant ThoughtSpot embedded instances too. +Set `enableLinkOverridesV2` to `true` in the Visual Embed SDK. Once enabled, all links will display host application URLs when hovered over or opened in a new tab. ThoughtSpot recommends using this enhanced configuration for your link override settings. [source,JavaScript] ---- @@ -229,12 +228,13 @@ const appEmbed = new AppEmbed(document.getElementById('ts-embed'), { }, pageId: Page.Home, showPrimaryNavbar: true, - linkOverride: true, + enableLinkOverridesV2: true, }); appEmbed.render(); ---- -Set `enableLinkOverridesV2` to `true` in the Visual Embed SDK. Once enabled, all links will display host application URLs when hovered over or opened in a new tab. ThoughtSpot recommends using this enhanced configuration for you link override settings. +If your ThoughtSpot instance uses the `linkOverride` in the Visual Embed SDK to override the link format of your embedded application pages and navigation links, this flag now gets auto-upgraded to `enableLinkOverridesV2` to ensure consistent link-override behavior. + [source,JavaScript] ---- @@ -245,10 +245,12 @@ const appEmbed = new AppEmbed(document.getElementById('ts-embed'), { }, pageId: Page.Home, showPrimaryNavbar: true, - enableLinkOverridesV2: true, + linkOverride: true, }); appEmbed.render(); ---- +[NOTE] +The `disableRedirectionLinksInNewTab` overrides these flags. When set to `true`, the link override settings will not work. == Verify system-generated links diff --git a/modules/ROOT/pages/embed-pinboard.adoc b/modules/ROOT/pages/embed-pinboard.adoc index 131108899..3d8d67eee 100644 --- a/modules/ROOT/pages/embed-pinboard.adoc +++ b/modules/ROOT/pages/embed-pinboard.adoc @@ -209,20 +209,17 @@ image::./images/liveboard-refresh.png[Liveboard refresh] The Visual Embed SDK also provides the following action IDs and events to customize the cache refresh visibility and workflow. -[width="100%",cols="2,1,4"] +[width="100%",cols="2,4"] |==== -|API | Description +|ID | Description -|`Action.RefreshLiveboardBrowserCache` -|xref:Action.adoc#_refreshliveboardbrowsercache[Action] +|xref:Action.adoc#_refreshliveboardbrowsercache[Action.RefreshLiveboardBrowserCache] |Action ID to show, hide, or disable the *Refresh* button in the Liveboard header. -|`EmbedEvent.RefreshLiveboardBrowserCache` -|xref:EmbedEvent.adoc#_refreshliveboardbrowsercache[EmbedEvent] +|xref:EmbedEvent.adoc#_refreshliveboardbrowsercache[EmbedEvent.RefreshLiveboardBrowserCache] |Emitted when a user clicks the *Refresh* button in the Liveboard header. -|`HostEvent.RefreshLiveboardBrowserCache` -|xref:HostEvent.adoc#_refreshliveboardbrowsercache[HostEvent] +|xref:HostEvent.adoc#_refreshliveboardbrowsercache[HostEvent.RefreshLiveboardBrowserCache] |Triggers a browser cache refresh programmatically for all visualization containers on the embedded Liveboard. |==== diff --git a/modules/ROOT/pages/mcp-server-changelog.adoc b/modules/ROOT/pages/mcp-server-changelog.adoc index 28b2d30c9..abb14bda8 100644 --- a/modules/ROOT/pages/mcp-server-changelog.adoc +++ b/modules/ROOT/pages/mcp-server-changelog.adoc @@ -25,6 +25,32 @@ This changelog lists the new features, enhancements, and other changes introduce // ============================================================ +== July 2026 +*API version string:* `?api-version=2026-05-01` + +*Upgrade notes*: Existing integrations using `?api-version=2026-05-01` or `?api-version=latest` will be automatically upgraded. + +[.cl-table, cols="1,4", frame=none, grid=none] +|==== +a| +[.cl-label] +*2026-07-10* + +a| + +[discrete] +==== Org switching tools +The OAuth MCP Server endpoints support the following MCP tools to discover the user's current Org and allow multi-Org users to switch to another Org mid-session without logging out or re-authenticating. + +* `list_orgs`: Returns a list of the Orgs that the ThoughtSpot account is currently an active member of, along with the Org used for the user session. +* `switch_org`: Switches the active Org for the current session. + +For more information, see xref:mcp-tool-reference-spotter3.adoc#org-switching-tools[Org switching tools]. + +[IMPORTANT] +The Org switching MCP tools are not available on Bearer-token connections. + +|==== + == May 2026 *API version string:* `?api-version=2026-05-01`. + @@ -61,6 +87,7 @@ Spotter MCP Server URLs now support date-based versioning, defined using the `?a ==== MCP tools and processing model [.version-badge.breaking]#Breaking# The MCP Server URL now points to the Spotter 3-powered MCP tools. With this enhancement, the legacy tools in your existing integrations will be replaced with new tools. If your app uses custom workflows, you must update your integrations to use the new MCP tools or pin a previous version using the `?api-version={YYYY-MM-DD}` parameter in the URL to preserve your existing changes. +[discrete] ===== Migration guidelines Migrating from your existing setup to the new version requires updating the MCP client configuration to point to the new URL and rewriting tool-calling logic to use the new asynchronous, polling model. @@ -105,6 +132,6 @@ Supports the following URLs: * `\https://agent.thoughtspot.app/bearer/mcp` (Bearer Token Apps) * `\https://agent.thoughtspot.app/openai/mcp` (OpenAI-compatible clients) -These URLs are deprecated as of the MCP Server 2026-05-01 release. See the xref:mcp-server-changelog.adoc#_mcp_server_url_changes_and_api_versioning[changelog] for more information. +These URLs are deprecated as of the MCP Server 2026-05-01 release. See the xref:mcp-server-changelog.adoc#_mcp_server_url_changes_and_api_versioning_breaking[changelog] for more information. |==== diff --git a/modules/ROOT/pages/mcp-server-spotter3.adoc b/modules/ROOT/pages/mcp-server-spotter3.adoc index 56d5ee302..e5f7cdfaf 100644 --- a/modules/ROOT/pages/mcp-server-spotter3.adoc +++ b/modules/ROOT/pages/mcp-server-spotter3.adoc @@ -44,7 +44,6 @@ Optionally, the `additional_context` parameter can be included to inject new ext |**API versioning support** |Not available. |Supports date-based API versioning, which is identified in the MCP Server URL as `?api-version=YYYY-MM-DD`. -|| |==== The following figure illustrates the MCP architecture, tool calls, and workflow in the new MCP Server version: @@ -87,8 +86,11 @@ ThoughtSpot creates a dashboard and returns a `dashboard_id` and a 6. *User asks a follow-up question (optional)* + The user can ask a follow-up question in the same session. The agent calls `send_session_message` again using the same `analytical_session_id`. ThoughtSpot retains the full conversation context automatically. The agent returns to step 4 to poll for the follow-up response. -For more information about the tool calls, input parameters, and response output, see xref:mcp-tool-reference-spotter3.adoc[MCP tool reference (Spotter 3)]. +7. *User switches to a different Org (optional)* + +If the user belongs to more than one Org and connects over OAuth, the agent calls `list_orgs` to return all accessible Orgs and flags the Org that the user is currently logged in. When the user requests a switch, the agent calls `switch_org` with the target `org_id`. For more information, see xref:mcp-tool-reference-spotter3.adoc#org-switching-tools[Org switching tools]. == Additional resources * For information about MCP, see the link:https://modelcontextprotocol.io[Model Context Protocol specification, window=_blank]. * For implementation details, see the link:https://github.com/thoughtspot/mcp-server[MCP Server GitHub repository, window=_blank]. + + diff --git a/modules/ROOT/pages/mcp-tool-reference-spotter3.adoc b/modules/ROOT/pages/mcp-tool-reference-spotter3.adoc index 509fb4d6b..b2a21dbd5 100644 --- a/modules/ROOT/pages/mcp-tool-reference-spotter3.adoc +++ b/modules/ROOT/pages/mcp-tool-reference-spotter3.adoc @@ -15,7 +15,11 @@ Send a natural language question or follow-up. * <> + Poll for streamed responses. * <> + -Create a Liveboard from session answers. +Create a dashboard from session answers. +* <> + +List the Orgs your account can access. (OAuth connections on Org-enabled instances only) +* <> + +Switch your active Org for the current session. (OAuth connections on Org-enabled instances only) * <> + Verify that the MCP Server is reachable. @@ -374,6 +378,141 @@ The following features are not supported directly. However, you can use the *Mak * Show underlying data, view query SQL or query visualizer * SpotIQ analysis +[#org-switching-tools] +== Org switching tools +Some ThoughtSpot deployments use Orgs, the isolated tenant workspaces within a single instance, each with its own users, data models, and resources. A user may have membership in one or several Orgs and want to analyze data from a different Org without ending the session, closing the connection, or re-authenticating. When connecting to the MCP Server over OAuth on an Org-enabled instance, users can discover and switch between Orgs during a session using `list_orgs` and `switch_org`. + +Org switching is a two-step pattern: + +. The agent calls `list_orgs` to retrieve the Orgs the user can currently access. The response identifies which Org is active and returns the `id` of the Orgs to switch. +. The agent calls `switch_org` with the target `org_id`. ThoughtSpot switches the active Org for the session and confirms the new active Org ID. + + +[IMPORTANT] +==== +* The `list_orgs` and `switch_org` tools are available on xref:mcp-integration.adoc#_mcp_server_url[OAuth MCP server endpoints] only. Bearer-token MCP Server endpoints do not expose these tools. +* The `switch_org` is a state-changing operation. Host applications that gate state-changing tools behind user confirmation will prompt the user before this tool runs. +* `list_orgs` reflects the user's current org membership at call time, not a snapshot taken at connection. Orgs granted or revoked mid-session appear immediately. +* Data models and resources in a target Org are not visible until after switching. Use `list_orgs` to discover Org names, then `switch_org` to enter an Org and explore its contents. +==== + +[#list_orgs] +=== list_orgs +Returns the `orgId` of the Orgs that the authenticated user has access to and flags the Org that the user is currently logged in to. + +Use the `list_orgs` tool to discover which Orgs you can reach before switching. The list always reflects your live access at call time, not a snapshot taken when you connected, so orgs granted or revoked since your session started are reflected immediately. + +==== Example call + +[div tabbed-code] +-- +[source,javascript] +---- +const orgs = await callMCPTool("list_orgs", {}); +---- + +[source,python] +---- +call_mcp_tool("list_orgs", {}) +---- +-- + +==== Response + +[source,json] +---- +{ + "orgs": [ + { + "id": 1001, + "name": "Finance", + "description": "Finance org — Q3 revenue models and budget data.", + "is_active": true + }, + { + "id": 1002, + "name": "Staging", + "description": "Staging environment for testing new data models." + } + ] +} +---- + +[cols="2,4", options="header"] +|==== +|Field|Description + +|`id`|Unique identifier for the Org. Pass this value to `switch_org` to switch to this Org. +|`name`|Display name of the Org. +|`description`|Description of the Org. +|`is_active`|Set to `true` if the user's current session is in this Org (the active Org). If the user's current session is not in this Org, this field is omitted from the response. +|==== + +[#switch_org] +=== switch_org +Switches the active Org for the current session. + +After a successful switch, all subsequent tool calls including `create_analysis_session` and data source lookups run against the Org to which the user is switched. This switch persists across all active sessions without requiring re-authentication or logging out. + +[IMPORTANT] +==== +* `switch_org` is a state-changing tool (`readOnlyHint: false`). Host applications that gate state-changing tools behind user confirmation will prompt the user before this tool runs. +* The data models that exist in a target Org cannot be viewed or accessed until after you have switched into it. Use `list_orgs` to discover available Orgs and then use `switch_org` to switch. +* After switching Orgs, the list of data model resources will stay static unless the LLM client provides dynamic resource lists. +* The active Org selection persists across sessions and applies across all your active sessions. It resets only on re-authentication or after prolonged inactivity. +==== + +==== Input parameters + +[cols="2,4", options="header"] +|==== +|Field|Description + +|`org_id` + +__Required__|The ID of the org to switch to. Obtain this value from `list_orgs`. +|==== + +=== Example call + +[div tabbed-code] +-- +[source,javascript] +---- +const result = await callMCPTool("switch_org", { + org_id: 1002 // ID of the org to switch to, obtained from list_orgs. +}); +---- + +[source,python] +---- +call_mcp_tool( + "switch_org", + {"org_id": 1002}, # ID of the org to switch to, obtained from list_orgs. +) +---- +-- + +=== Response + +[source,json] +---- +{ + "success": true, + "active_org_id": 1002 +} +---- + +* `success`: `true` if the org switch completed successfully. If the user lacks access to the requested Org, it is set as `false` and the active Org remains unchanged. +* `active_org_id`: The ID of the active Org. + + +=== Known limitations + +* Signing in currently relies on a browser cookie from your ThoughtSpot cluster. If your browser blocks third-party cookies, the connection may fail to complete. +* Re-authentication is required in the following scenarios: +** If connection remains idle for 14 days, the session expires and requires reauthentication. +** If your ThoughtSpot instance is temporarily unreachable when your session token renews, you may be signed out and prompted to reconnect. + [#check_connectivity] == check_connectivity Runs a basic health check to verify that the ThoughtSpot Spotter MCP Server is reachable and responding. Use this tool to confirm your connection before starting an analytical session. diff --git a/modules/ROOT/pages/spottercode-integration.adoc b/modules/ROOT/pages/spottercode-integration.adoc index 31209817e..6abc417da 100644 --- a/modules/ROOT/pages/spottercode-integration.adoc +++ b/modules/ROOT/pages/spottercode-integration.adoc @@ -15,6 +15,52 @@ This guide walks you through the process of adding SpotterCode to your IDE. * Ensure that the latest version of Node.js is installed in your environment. This is required for building embedding code with the SDK. * Ensure that you have access to a ThoughtSpot instance and can view the objects and resources that you want to embed or access via the REST API. +[#_authenticate_spottercode] +== Authentication +Starting with July 2026, the SpotterCode MCP Server endpoint requires you to authenticate with a ThoughtSpot instance. This allows SpotterCode to perform authenticated user operations using ThoughtSpot REST APIs. + +SpotterCode supports two authentication mechanisms: + +* OAuth and SAML authentication +* Bearer token authentication + +=== OAuth and SAML authentication + +This is the primary authentication flow for developers connecting an MCP client interactively. + +. When your MCP client connects to the `https://spottercode.thoughtspot.app/mcp` endpoint for the first time, a dialog appears requesting your ThoughtSpot instance URL. +. Enter your ThoughtSpot instance URL (for example, `https://your-org.thoughtspot.cloud`). +. You are redirected to the ThoughtSpot SAML login flow for your instance. +. After successful login, SpotterCode obtains a bearer token for your session and stores the session information securely. +. Subsequent MCP requests from your IDE agent use the session token automatically and you will not be prompted to log in again until the session expires. + +[NOTE] +==== +The session token is stored in a secure backend store. Contact your ThoughtSpot administrator if you encounter repeated authentication prompts. +==== + +=== Bearer token authentication +For programmatic or CI/CD scenarios where an MCP client cannot perform an interactive login, SpotterCode accepts a bearer token directly. + +In your MCP client configuration, pass the `Authorization` header in the following format: + +[source,text] +---- +Authorization: Bearer @ +---- + +Where: + +* `` is a valid ThoughtSpot bearer token obtained from the ThoughtSpot REST API. +* `` is your ThoughtSpot instance hostname (for example, `your-org.thoughtspot.cloud`). + +SpotterCode extracts and validates the token and host, then injects the authentication context into each MCP tool request. + +[TIP] +==== +To obtain a bearer token, use the xref:authentication.adoc[ThoughtSpot REST API v2 authentication endpoints] or trusted authentication. For more information, see xref:trusted-authentication.adoc[Trusted authentication]. +==== + == Integrate SpotterCode with Cursor You can add the SpotterCode MCP Server URL to Cursor using the one-click installation link or the `mcp.json` file. @@ -25,7 +71,7 @@ Via Cursor Marketplace:: SpotterCode is available as an official plugin in the link:https://cursor.com/marketplace/thoughtspot[Cursor Marketplace, window=_blank]. To install SpotterCode from the Cursor Marketplace: . Go to link:https://cursor.com/marketplace/thoughtspot[Cursor Marketplace, window=_blank]. . Ensure that you are signed in, and then click **Add to Cursor** -> **Add Plugin**. -. To view the plugin in Cursor, click *View in Editor*. +. To view the plugin in Cursor, click **View in Editor**. Via installation link:: . Copy the following link and open it in Cursor: + @@ -58,10 +104,8 @@ Cursor also allows you to integrate SpotterCode by adding the MCP server URL in } } ---- -. Click *Save* and close the `mcp.json` file. This installs the SpotterCode MCP server and makes its tools available for AI models in Cursor. - - -For information about configuring MCP servers in Cursor, refer to the link:https://cursor.com/docs/context/mcp[Cursor Documentation, window=_blank]. +. Click **Save** and close the `mcp.json` file. +. In **Cursor Settings** > **Tools and MCP**, click **Connect**. You will be prompted to provide the URL of your ThoughtSpot instance and complete authentication. If the authentication is successful, the SpotterCode MCP server makes its tools available for AI models in Cursor. == Integrate SpotterCode with Claude @@ -74,10 +118,11 @@ To add SpotterCode as a custom connector: . Go to **Customize** > **Connectors** . Click the `+` icon and select **Add custom connector**. -. Enter the SpotterCode MCP server URL: `https://spottercode.thoughtspot.app/mcp`. +. Enter the SpotterCode MCP server URL. . Click **Add**. +. When prompted for authentication, specify the URL of your ThoughtSpot instance and complete authentication. -This configuration automatically enables SpotterCode in Claude AI chat and Claude Code for users of the Claude account. +//This configuration automatically enables SpotterCode in Claude AI chat and Claude Code for users of the Claude account. === Claude Code-only setup @@ -88,6 +133,8 @@ To enable SpotterCode in Claude Code, add the MCP server URL using the following claude mcp add --transport http SpotterCode https://spottercode.thoughtspot.app/mcp ---- +When prompted for authentication, specify the URL of your ThoughtSpot instance and complete authentication. + === Claude Desktop integration If you are using Claude Desktop, add the URL directly to the Claude configuration JSON file: @@ -102,17 +149,17 @@ If you are using Claude Desktop, add the URL directly to the Claude configuratio } ---- +When prompted for authentication, specify the URL of your ThoughtSpot instance and complete authentication. + === Claude Cowork integration If you are using Claude Cowork with Claude AI or Claude Desktop, verify whether the SpotterCode MCP connector is enabled for Claude Cowork. If it's not enabled, add the SpotterCode MCP server: -. Open Claude Cowork either in Claude AI or Claude Desktop app. +. Open Claude Cowork in either Claude AI or the Claude Desktop app. . Navigate to **Settings** > **Connectors** > **Customize**. . If SpotterCode is already available in your organization's list of connectors, select the SpotterCode connector. If it's not available: .. Click the `+` icon and select **Add custom connector**. .. Add the SpotterCode MCP server URL: `\https://spottercode.thoughtspot.app/mcp`. - -//For more information about adding MCP servers to Claude Code, see link:https://code.claude.com/docs/en/mcp[Claude Code Documentation, window=_blank]. - +. When prompted for authentication, specify the URL of your ThoughtSpot instance and complete authentication. == Integrate SpotterCode with Visual Studio Code @@ -132,7 +179,48 @@ To add the SpotterCode MCP Server to Visual Studio Code, use the Extensions view } ---- -After you add the MCP server URL, the SpotterCode MCP server is available in the Extensions view. For more information about configuring MCP servers in Visual Studio Code, refer to link:https://code.visualstudio.com/docs/copilot/customization/mcp-servers[Visual Studio Code Documentation, window=_blank]. +When prompted for authentication, specify the URL of your ThoughtSpot instance and complete authentication. + +After you add the MCP server URL, the SpotterCode MCP server is available in the Extensions view. + +=== Configuring MCP Server endpoint for documentation retrieval only + +If you only need documentation and REST API reference retrieval, use the following unauthenticated MCP Server URL: `\https://spottercode.thoughtspot.app/mcp/docs`. + +This endpoint provides access to the `get-rest-api-reference` and `get-developer-docs-reference` skills only. The `run-ts-workflow` skill is not available through this endpoint. + +To use this endpoint in your IDE, replace the authenticated MCP server URL in your configuration: + +For Cursor (`mcp.json`):: +[source,JSON] +---- +{ + "mcpServers": { + "SpotterCode": { + "url": "https://spottercode.thoughtspot.app/mcp/docs" + } + } +} +---- + +For Claude Code (CLI):: +[source,Bash] +---- +claude mcp add --transport http SpotterCode https://spottercode.thoughtspot.app/mcp/docs +---- + +For Visual Studio Code (`mcp.json`):: +[source,JSON] +---- +{ + "servers": { + "SpotterCode": { + "url": "https://spottercode.thoughtspot.app/mcp/docs", + "type": "http" + } + } +} +---- == Verify the integration @@ -143,6 +231,8 @@ To verify the integration: If the integration is successful, you'll see SpotterCode in the MCP servers list. . Verify the available SpotterCode skills. + +//// + For example, Cursor shows the skills of MCP connectors in the **Tools and MCP** page. Check if the xref:spottercode.adoc#_supported_skills[SpotterCode MCP skills] appear under SpotterCode. As you hover over each skill, you can view the description and input schema used for agentic interactions. You can also disable the MCP skills that you don't want the AI model to use. @@ -151,7 +241,7 @@ For example, Cursor shows the skills of MCP connectors in the **Tools and MCP** -- video::./images/cursor_mcp-skills.mp4[width=100%,options="autoplay,loop"] -- - +//// . Initiate a chat session and ask a question related to ThoughtSpot embedding, REST APIs, or the SDKs. + In the following example, a chat session with Cursor AI is initiated with the prompt, "I want to embed a ThoughtSpot Liveboard in my React application. Use the available tools to get this information and generate the embed code". Notice how the AI agent uses the SpotterCode skills to get the required information: @@ -184,13 +274,15 @@ video::./images/cursor-lb-embed.mp4[width=100%,options="autoplay,loop"] * For prompt examples, see xref:spottercode-prompt-guide.adoc#_prompt_examples[Prompt examples and best practices]. * For troubleshooting tips and workarounds, refer to the xref:spottercode-prompt-guide.adoc#_troubleshooting_errors[Troubleshooting] section. - +* For more information about adding MCP servers to Claude Code, see link:https://code.claude.com/docs/en/mcp[Claude Code Documentation, window=_blank]. +* For information about configuring MCP servers in Cursor, refer to the link:https://cursor.com/docs/context/mcp[Cursor Documentation, window=_blank]. +* For more information about configuring MCP servers in Visual Studio Code, refer to link:https://code.visualstudio.com/docs/copilot/customization/mcp-servers[Visual Studio Code Documentation, window=_blank]. //// . If your IDE shows the step-by-step explanation of how the Agent how the AI reached its conclusion, you may see the following parameters. These parameters show the input schema of the MCP request to SpotterCode. * `query` - User's request or question. For example, `how do I embed Liveboard`. * `version` - Version of the SDK to use. Default is `latest`. -* `topK` - How many relevant documents to return for the query. Default is 5. The agent may increase or decreased the number to get the right answer. +* `topK` - How many relevant documents to return for the query. Default is 5. The agent may increase or decrease the number to get the right answer. * `symbolName` - Limiting search to a specific item, for example, `LiveboardEmbed`. * `apiName` - The API node for finding request/response details. * `additionalDocs` - To include more documentation for extra context, such as Java or TypeScript SDK guidance. diff --git a/modules/ROOT/pages/spottercode.adoc b/modules/ROOT/pages/spottercode.adoc index 968b3150d..b6c3c133d 100644 --- a/modules/ROOT/pages/spottercode.adoc +++ b/modules/ROOT/pages/spottercode.adoc @@ -6,32 +6,88 @@ :page-pageid: SpotterCode :page-description: Use SpotterCode to accelerate code generation and the process of embedding and integrating ThoughtSpot. -ThoughtSpot’s SpotterCode is an AI-powered MCP tool that streamlines and speeds up the process of embedding ThoughtSpot content and integrating ThoughtSpot REST APIs in your application workflows. +ThoughtSpot's SpotterCode is an AI-powered MCP tool that streamlines and speeds up the process of embedding ThoughtSpot content and integrating ThoughtSpot REST APIs in your application workflows. == What is SpotterCode? SpotterCode connects your integrated development environment (IDE) to a ThoughtSpot-hosted MCP server. It empowers AI-native IDEs with tools and documentation lookup capabilities, providing direct access to ThoughtSpot SDKs, REST API documentation, code samples, and developer guides. The AI agents in the IDE can use these skills to assist developers in embedding ThoughtSpot content and integrating REST API workflows into their applications. -[IMPORTANT] +== Who should use SpotterCode? +SpotterCode is designed for developers and technical teams who embed ThoughtSpot content or integrate ThoughtSpot REST APIs into their applications using AI-native IDEs such as Cursor, Visual Studio Code with GitHub Copilot, or Claude Code. + +When integrated, SpotterCode accelerates the process of embedding and integration by providing code samples, SDK skills, and custom styling directly in the IDE. It enables developers to build context-aware and deployment-ready code tailored to their project structure, thereby reducing manual effort and errors. + +SpotterCode is useful at every stage of an embedded ThoughtSpot project: + +* *Setting up a new embedded project* + +Use the authenticated `/mcp` endpoint so the IDE agent can configure your ThoughtSpot instance directly. You can generate a trusted authentication secret key, add your application domain to CORS and CSP allowlists, and retrieve Liveboard and Answer object IDs, all without leaving your IDE. + +* *Writing and reviewing embed code* + +SpotterCode gives your IDE agent direct access to Visual Embed SDK and REST API documentation, code samples, and developer guides. The agent can generate context-aware embed code tailored to your project structure and provide direct access to the SDK reference. + +* *Integrating REST API workflows* + +Access up-to-date REST API specifications, request and response formats, authentication flows, and TypeScript and Java SDK references to accelerate API integration. + +* *Looking up documentation* + +SpotterCode empowers your IDE with documentation lookup capabilities and provides direct access to authoritative information on embedding ThoughtSpot or integrating REST API workflows in your development projects. + +[NOTE] ==== -SpotterCode is an add-on tool available with the link:https://www.thoughtspot.com/pricing[ThoughtSpot Analytics and ThoughtSpot Embedded offerings, window=_blank]. If you have a ThoughtSpot Analytics license with an active ThoughtSpot Embedded subscription, you can integrate SpotterCode using the SpotterCode MCP Server URL in your coding application. +SpotterCode is an acceleration tool designed to help developers streamline the process of integrating ThoughtSpot into their projects. It does not replace the Visual Embed SDK or the foundational knowledge required for embedding or application integration. ==== -== Who should use SpotterCode? -SpotterCode is intended for developers and technical teams integrating ThoughtSpot content and workflows into their applications using Visual Embed SDK and REST APIs, with a particular focus on those working in AI-native IDEs such as Cursor. +[#_mcp_server_endpoints] +== MCP server endpoints +SpotterCode is an add-on tool available with the link:https://www.thoughtspot.com/pricing[ThoughtSpot Analytics and ThoughtSpot Embedded offerings, window=_blank]. If you have a ThoughtSpot Analytics license with an active ThoughtSpot Embedded subscription, you can integrate SpotterCode using the SpotterCode MCP Server URL in your coding application. + +ThoughtSpot provides the following MCP server endpoints for SpotterCode: + +[cols="1,2,2", options="header"] +|==== +| Endpoint | URL | Available tools +| *Authenticated endpoint* + +(`/mcp`) +| `\https://spottercode.thoughtspot.app/mcp` + +The full-capability SpotterCode endpoint. Requires authentication with a ThoughtSpot instance. You can use this MCP endpoint to perform authenticated user operations on your ThoughtSpot instance via the public REST APIs. +| `get-rest-api-reference` + +`get-developer-docs-reference` + +`execute-thoughtspot-code` + +| *Documentation endpoint* + +(`/mcp/docs`) +| `\https://spottercode.thoughtspot.app/mcp/docs` + +This endpoint includes documentation retrieval skills only and doesn't require authentication. Use this endpoint if you only need the AI agent to look up ThoughtSpot developer documentation and REST API reference, without connecting to a live ThoughtSpot instance. +| `get-rest-api-reference` + +`get-developer-docs-reference` +|==== + +== Supported MCP tools +SpotterCode provides the following skills to the AI agent in your IDE. Authenticated skills require a valid ThoughtSpot session established through the xref:spottercode-integration.adoc#_authenticate_spottercode[SpotterCode authentication flow]. -When integrated, SpotterCode offers the following advantages: +* `get-rest-api-reference` + +Provides REST API specifications, endpoints, request/response formats, authentication flows, CRUD operations, and SDKs for TypeScript and Java. -* Empowers your IDE with the documentation lookup and provides direct access to authoritative information on embedding ThoughtSpot or integrating REST API workflows in your development projects. +* `get-developer-docs-reference` + +Provides access to documentation on embedding, UI customization, deployment, security, and best practices. -* Accelerates the process of embedding and integration by providing code samples, SDK skills, and custom styling directly in the IDE. +* `execute-thoughtspot-code` + +Executes authenticated ThoughtSpot API workflows directly from your IDE agent. This skill allows your IDE agent to perform common operations that can be done via public REST APIs. -* Enables developers to build context-aware and deployment-ready code tailored to their project structure, thereby reducing manual effort and errors. +=== Choosing the right endpoint +Use the following guidance to decide which endpoint to configure in your IDE: -* Reduces operational strain by rapidly generating boilerplate code required for embedding ThoughtSpot in your application. +* *Use `/mcp` (authenticated)* if: +** You want the AI agent to execute ThoughtSpot API workflows from your IDE, for example, to generate a trusted authentication secret key, configure your application domain in CORS/CSP allowlists, or retrieve Liveboard and Answer object IDs from your instance. +** You want your IDE to use the full set of SpotterCode skills, including `run-ts-workflow`. +** You are building or configuring a ThoughtSpot embedded application and want end-to-end setup assistance without leaving the IDE. + +* *Use `/mcp/docs` (unauthenticated)* if: +** You only need the AI agent to look up documentation, REST API reference material, and code samples. +** You are working in an environment where connecting to a ThoughtSpot instance is not appropriate. For example, a shared CI environment, a read-only developer workstation, or a demonstration setup. +** You do not have a ThoughtSpot Embedded subscription or instance credentials available. [NOTE] ==== -SpotterCode is an acceleration tool designed to help developers streamline the process of integrating ThoughtSpot into their projects. It does not replace the Visual Embed SDK or the foundational knowledge required for embedding or application integration. +The IDE configuration steps in this guide use the authenticated `/mcp` endpoint by default. If you want to use the unauthenticated `/mcp/docs` endpoint instead, replace the endpoint URL in the relevant configuration snippet before saving. All other configuration steps remain the same. ==== == Supported IDEs @@ -42,23 +98,9 @@ The initial version of SpotterCode supports the following IDEs: * Visual Studio Code with GitHub Copilot * Claude Code -== Supported skills -SpotterCode provides the following skills to the AI agent on your IDE: - -//// -* `get-visual-embed-sdk-reference` + -A documentation lookup skill that accesses Visual Embed SDK documentation and generates code samples for embedding ThoughtSpot content, including supported embed types, authentication, configuration, customization, event hooks, and code samples. -//// - -* `get-rest-api-reference` + -Provides REST API specifications, endpoints, request/response formats, authentication flows, CRUD operations, and SDKs for TypeScript and Java. - -* `get-developer-docs-reference` + -Provides access to documentation on embedding, UI customization, deployment, security, and best practices. - == Limitations -* Responses from SpotterCode are determined by the features and parameters currently supported in the Visual Embed SDK, REST API, and official ThoughtSpot Developer documentation. SpotterCode cannot generate code or solutions that rely on unsupported or undocumented features. +* Responses from SpotterCode are determined by the features and parameters currently supported in the Visual Embed SDK, REST API, and official ThoughtSpot developer documentation. SpotterCode cannot generate code or solutions that rely on unsupported or undocumented features. * SpotterCode can generate code samples for the most common use cases. Scenarios that require advanced customization or highly specialized workflows may require manual intervention or additional coding beyond what SpotterCode provides. * SpotterCode does not influence how the Spotter feature in your ThoughtSpot embed infers semantic modeling. SpotterCode is not intended for querying data models or interpreting definitions such as measures and attributes in your metadata objects. * The behavior of the IDE agent, including tool selection and reasoning, is not controlled by SpotterCode. diff --git a/modules/ROOT/pages/timezone.adoc b/modules/ROOT/pages/timezone.adoc index 59b43476a..839794371 100644 --- a/modules/ROOT/pages/timezone.adoc +++ b/modules/ROOT/pages/timezone.adoc @@ -7,8 +7,6 @@ :page-description: Configure per-Org and per-user timezone settings in embedded ThoughtSpot deployments using the Variable API, so that all relative date and time keywords resolve correctly for every user. :keywords: timezone, ts_user_timezone, Variable API, date keywords, embedded, TSE, Org timezone, user timezone -[earlyAccess eaBackground]#Early Access# - The timezone awareness feature in ThoughtSpot allows you to configure a preferred timezone for a user or at the Org level, or both, and apply this timezone when generating search results for a user's query. == Overview @@ -242,8 +240,7 @@ If the `ts_user_timezone` variable is configured for the Org or user, you can re The following example shows the formula syntax with the `ts_user_timezone` variable: -`sql_date_time_op ("CONVERT_TIMEZONE ('UTC', {0}, {1}"), ts_var (ts_user_timezone), [])` - +`sql_date_time_op ("CONVERT_TIMEZONE ('UTC', {0}, {1})", ts_var(ts_user_timezone), [])` Where: @@ -265,9 +262,7 @@ On query execution, the formula translates to: === Using hardcoded timezone values in formulas In ThoughtSpot Cloud 26.5.0.cl and earlier release versions, the timezone value was hardcoded in formulas to convert source values to the user's timezone. For example: ----- -sql_date_time_op ("CONVERT_TIMEZONE ('UTC', {0}, {1}"), '', []) ----- +`sql_date_time_op ("CONVERT_TIMEZONE ('UTC', {0}, {1})", '', [])` Where: @@ -294,6 +289,12 @@ To verify the configuration: * Verify whether the timezone configured for the user overrides the timezone set for the Org and system default on the ThoughtSpot instance. * Verify the Liveboard scheduled jobs. Note that the timezone changes will be applied only to the upcoming scheduled job executions. +== Limitations +On instances with a non-UTC timezone, during Daylight Saving Time (DST) transitions, queries using `Last X Hours` or `Next X Hours` filters on datetime columns may fail if the selected time range crosses a DST boundary. ThoughtSpot displays a generic query error in these cases. + +To work around this issue, modify the relative hour filter (for example, change `Last 24 Hours` to `Last 23 Hours` or `Last 25 Hours`) or use an equivalent date-based filter where applicable. + +To avoid this issue, change your cluster timezone to UTC. == Additional resources diff --git a/modules/ROOT/pages/tml.adoc b/modules/ROOT/pages/tml.adoc index 9ffba0d70..68ecbb00b 100644 --- a/modules/ROOT/pages/tml.adoc +++ b/modules/ROOT/pages/tml.adoc @@ -29,10 +29,14 @@ See the following pages for the detailed syntax of TML files for each object typ For TML modification tips and recommendations, see xref:modify-tml.adoc[TML modification]. + +//// [NOTE] ==== -Worksheets are deprecated in ThoughtSpot and replaced by Models from 10.12.0.cl onwards. +Worksheets are deprecated in ThoughtSpot and replaced by Models. ==== +//// + == TML import and export via REST API @@ -58,17 +62,6 @@ To import TML representation of the metadata objects into ThoughtSpot, use one o * xref:tml-api.adoc#import[POST /tspublic/v1/metadata/tml/import] (REST API v1) //While the v1 API accepts a string containing a JSON array of TML objects to upload, in YAML or JSON format, the v2 accepts it only in the JSON format. - -There are multiple kinds of imports possible: - -* `PARTIAL` imports all objects that validate successfully, and ignores objects that do not validate successfully. -* `ALL_OR_NONE` imports the objects that validate successfully. -* `VALIDATE_ONLY` validates the objects but does not import them. -* `PARTIAL_OBJECT` (only applicable to REST API v2) -imports objects that validate successfully and skips the objects that do not validate successfully. If the import fails for a visualization object in a Liveboard TML, the Liveboard will be imported without that visualization object. Similarly, if importing a relationship in a logical table fails, the table TML will be imported with warnings in the API response. - -You can also specify additional parameters to set the Org context and skip CDW validation checks for Table TMLs. - [NOTE] ==== If you import only a Model object, it may take some time for the Model to become available in the ThoughtSpot system. You may need to wait for a few seconds to create answers and Liveboards. @@ -87,6 +80,156 @@ Creates an import TML tasks and processes TMLs asynchronously * +++POST /api/rest/2.0/metadata/tml/async/status+++ + Fetches status of import tasks +=== Best practices for async TML import + +Use the following guidelines to configure and manage async TML import tasks effectively. + +==== Choose the right import policy + +[width="100%", cols="1,3,2,2"] +[options='header'] +|==== +|Policy|Behavior|Recommended use case|Limits and risks + +|`ALL_OR_NONE` +|All objects are validated and saved in a single database write. +If any object fails, no objects are written. +|Small, tightly coupled object sets requiring atomicity. +|Limit to approximately 50 TML objects per task. +Exceeding this risks OOM errors or database write failures. +Liveboard size affects this limit; Liveboards averaging approximately 30 visualizations are a useful sizing baseline. + +|`VALIDATE_ONLY` +|Objects are validated in memory. +No changes are written to the database. +|Pre-import validation before committing to a production import. +|All changes accumulate in memory. +Very large tasks risk OOM errors. + +|`PARTIAL` +|Objects that pass validation are written. +Failed objects are skipped without dropping subentities. +If a subentity (such as a visualization) fails, the parent object (such as a Liveboard) also fails and is not written. +|Large-scale migrations where some failures are expected. +Resubmit failed objects as a new task after fixing errors. +|Recommended policy for large imports. +Objects are written incrementally, reducing memory pressure. + +|`PARTIAL_OBJECT` +|Objects that pass validation are written. +If a subentity (visualization, join, or RLS rule) fails, the parent object is written with a warning and the failed subentity is dropped. +|Large-scale migrations where pipeline continuity matters more than completeness. +|Recommended when a missing visualization or dropped join is acceptable in the target environment. +|==== + +[NOTE] +==== +If you use custom scripts to batch imports with `ALL_OR_NONE`, the net result across batches is effectively the same as `PARTIAL` behavior—some batches succeed and some fail. +Use the `PARTIAL` policy directly for large-volume imports rather than scripting `ALL_OR_NONE` batches. +==== + +[IMPORTANT] +==== +Use `PARTIAL` or `PARTIAL_OBJECT` for large import operations. +`ALL_OR_NONE` and `VALIDATE_ONLY` process all objects in memory or in a single database transaction, which can cause OOM errors on large tasks. +==== + +==== Size your import tasks + +* For `ALL_OR_NONE` and `VALIDATE_ONLY`, limit tasks to approximately 50 TML objects. +There is no hard code limit, but larger tasks risk OOM errors or failed database writes. +The safe upper bound depends on Liveboard complexity. +Liveboards with an average of approximately 30 visualizations each provide a reasonable sizing baseline. + +* For `PARTIAL` and `PARTIAL_OBJECT`, there is no per-task object limit enforced by the API. +These policies write objects incrementally and are appropriate for large migration workloads. + +* The API payload size limit is 500 MB per request (infrastructure limit). +Contact ThoughtSpot Support if your use case requires a larger limit. + +// TODO: verify with engineering — confirm whether the ~50-object guideline counts TML strings in the array, or total distinct objects including dependents. + +==== Avoid parallel imports of the same object + +Never submit tasks that include the same object in more than one active task simultaneously. +Concurrent writes to the same object cause a version conflict, and one of the tasks will fail. + +Design your import pipeline so that each object appears in at most one active import task at a time. +Sequence tasks, do not parallelize them across the same objects. + +==== Monitor the task queue and status + +The async import queue supports a maximum of 100 concurrent tasks. +Submitting more than 100 tasks at once causes the excess tasks to be rejected with a `FAILED` status immediately. + +Poll the `POST /api/rest/2.0/metadata/tml/async/status` endpoint to check task status. + +[width="100%", cols="1,4"] +[options='header'] +|==== +|Status value|Description + +|`IN_QUEUE` +|The task is waiting to be processed. +The queue limit is 100 concurrent tasks. +Tasks submitted beyond the limit are rejected immediately with status `FAILED`. + +|`IN_PROGRESS` +|The task is being processed. + +|`COMPLETED` +|The task processing is complete. +`COMPLETED` does not mean every object imported successfully. +Individual objects within the task have their own statuses. +Inspect per-object status in the response to identify failures. + +|`FAILED` +|The task failed. +This could be due to multiple reasons such as - the queue was full at submission time, a policy-level failure occurred, or an unrecoverable error was encountered during processing. +|==== + +*Recommended polling intervals:* + +The status API enforces a rate limit of 100 requests per minute. +Exceeding this limit returns an error. + +For practical use: + +* For small tasks, poll no more frequently than every 30 seconds. +* For large tasks, a polling interval of 1 minute is recommended, as larger tasks take proportionally longer to complete. + +==== Use API parameters correctly + +The following parameters in `POST /api/rest/2.0/metadata/tml/async/import` require careful use: + +`create_new`:: +Set `create_new: true` only when you want to create objects with new GUIDs, not update existing objects. +Setting this parameter on objects that already exist creates duplicates. +Do not set this parameter unless you are certain that new objects should be created. + +`skip_diff_check`:: +Set `skip_diff_check: true` only when you want to force a re-import of a TML file that has not changed since the previous import. +By default, ThoughtSpot identifies unchanged objects and skips them to reduce import time. +Enable this parameter only when unchanged files must be explicitly reprocessed. + +`enable_large_metadata_validation`:: +// TODO: verify with engineering — confirm purpose, behavior, and recommended use of `enable_large_metadata_validation` before publishing. +Set to `true` if the database contains multiple thousands of tables. +When enabled, ThoughtSpot validates schema one table at a time, which helps circumvent metadata fetching limitations of the Cloud Data Warehouse (CDW). +Default: `false`. + +`enable_personalized_view_upsert`:: +Set to `true` to enable update and insert of personalized views in a Liveboard during TML import. +When enabled, personalized views are preserved or created as part of the import operation instead of being discarded. +Default: `false`. + + +==== Schedule large imports during off-peak hours + +Large TML migrations can temporarily increase system resource usage. +Schedule bulk async imports during off-peak hours to reduce the risk of impacting users who are actively using the cluster. + + === Schedule import tasks You can import TML objects asynchronously by scheduling TML import tasks via `POST` request to POST `/api/rest/2.0/metadata/tml/async/import` API endpoint. You can send the following parameters in the API request body: @@ -103,24 +246,28 @@ __Optional__ |__Boolean__. Specify if import operation must be run for all Orgs __Requires Org administration privileges to access TML objects across all Orgs.__| `false` -|`import_policy` a|__String__. Available from 10.5.0.cl. Policy to follow during import. The allowed values are: +|`import_policy` a|__String__. Policy to follow during import. The allowed values are: -* `PARTIAL` + -Imports objects that validate successfully. Skips the objects that do not validate successfully and their dependent objects if any. -* `ALL_OR_NONE` + -Imports all objects that validate successfully. If the import fails for one object, no objects will be imported. -* `VALIDATE_ONLY` + -Validates the objects but does not import them. -* `PARTIAL_OBJECT` + -Imports objects that validate successfully and skips the objects that do not validate successfully. If the import fails for a visualization object in a Liveboard TML, the Liveboard will be imported without that visualization object. Similarly, if importing a relationship in a logical table fails, the table TML will be imported with warnings in the API response. +* `PARTIAL` +//Imports objects that validate successfully. Skips the objects that do not validate successfully and their dependent objects if any. +* `ALL_OR_NONE` +//Imports all objects that validate successfully. If the import fails for one object, no objects will be imported. +* `VALIDATE_ONLY` +//Validates the objects but does not import them. +* `PARTIAL_OBJECT` +//Imports objects that validate successfully and skips the objects that do not validate successfully. If the import fails for a visualization object in a Liveboard TML, the Liveboard will be imported without that visualization object. Similarly, if importing a relationship in a logical table fails, the table TML will be imported with warnings in the API response. | `PARTIAL_OBJECT` |`skip_diff_check` + __Optional__ -|__Boolean__. When set to `true`, skips the diff check before processing TML objects for import. By default, ThoughtSpot compares each TML object against its last imported version and skips objects that have not changed, which reduces unnecessary reimports. Set to `true` to bypass this check and reimport all objects regardless of whether they have changed. |`false` +|__Boolean__. |`false` |`enable_large_metadata_validation` + __Optional__ - |__Boolean__. Available from 10.5.0.cl. Enables validation for large metadata objects. Set to `true` if the database contains multiple thousands of tables. When enabled, it allows for schema validation of one table at a time and helps circumvent the metadata fetching limitations of the Cloud Data Warehouse (CDW). + |__Boolean__ +|`false` +|`enable_personalized_view_upsert` + +__Optional__ +|__Boolean__ |`false` |==== //// @@ -218,8 +365,6 @@ response starting from offset position. The maximum limit for the `record_size` that user can pass in an API request is 50. If the `record_size` exceeds this threshold, the API returns a bad request error. To extend the `record_size` limit, contact ThoughtSpot Support. ==== | `5` -|`include_import_response`|__Boolean__. Specify whether to include the import response when fetching status for the import task. - |==== [IMPORTANT] diff --git a/modules/ROOT/pages/whats-new.adoc b/modules/ROOT/pages/whats-new.adoc index dc99edbb4..e81daa1b5 100644 --- a/modules/ROOT/pages/whats-new.adoc +++ b/modules/ROOT/pages/whats-new.adoc @@ -26,7 +26,7 @@ This page lists new features, enhancements, and deprecated functionality introdu == July 2026 **Release version**: ThoughtSpot Cloud 26.7.0.cl + -*Upgrade notes*: No breaking changes + +*Upgrade notes*: Includes breaking changes to SpotterCode + *Recommended SDK versions*: Visual Embed SDK v1.50.0 and later [.cl-table, cols="2,4", frame=none, grid=none] @@ -65,6 +65,23 @@ In full application embedding with the V3 navigation and home page experience, T --- +[discrete] +==== SpotterCode authentication and workflow execution [.version-badge.breaking]#Breaking# +SpotterCode now supports authenticated sessions with your ThoughtSpot instance. When connecting your MCP client to the SpotterCode endpoint, you are now prompted to log in using your organization's identity provider. After authentication, SpotterCode can make ThoughtSpot API calls on your behalf. + +For more information, see the documentation on xref:spottercode.adoc#_mcp_server_endpoints[SpotterCode MCP Server] and xref:spottercode-integration.adoc#_authenticate_spottercode[Authenticating SpotterCode]. + +--- + +[discrete] +==== SpotterCode Agent in Visual Embed Playground [earlyAccess eaBackground]#Early Access# + +The Visual Embed SDK Playground now includes SpotterCode Agent, an AI-powered coding assistant. The SpotterCode panel displays pre-built prompts relevant to the component you are embedding, provides a prompt interface for user queries, and generates embed code. It generates boilerplate code automatically, accelerates building code and iterating embed configurations. + +For more information, see xref:developer-playground.adoc#spottercode-panel[Using SpotterCode in the Playground]. + +--- + [discrete] ==== Webhooks enhancements @@ -83,14 +100,6 @@ The xref:webhooks-api.adoc#_updating_a_webhook[webhook update API endpoint] supp --- -[discrete] -==== SpotterCode Agent in Visual Embed Playground [earlyAccess eaBackground]#Early Access# - -The Visual Embed SDK Playground now includes SpotterCode Agent, an AI-powered coding assistant. The SpotterCode panel displays pre-built prompts relevant to the component you are embedding, a prompt interface for user queries, and generates embed code. It generates boilerplate code automatically, accelerates building code and iterating embed configurations. - -For more information, see xref:developer-playground.adoc#spottercode-panel[Using SpotterCode in the Playground]. - ---- [discrete] ==== Org isolation for per-org SAML and OIDC authentication @@ -650,4 +659,4 @@ For information about the new features and enhancements introduced in Visual Emb ==== REST API For information about REST API v2 enhancements, see xref:rest-apiv2-changelog.adoc[REST API v2.0 changelog]. -|=== \ No newline at end of file +|=== diff --git a/src/components/DevDocTemplate/index.tsx b/src/components/DevDocTemplate/index.tsx index bb83b7d80..4b0ac293c 100644 --- a/src/components/DevDocTemplate/index.tsx +++ b/src/components/DevDocTemplate/index.tsx @@ -53,6 +53,10 @@ import t from '../../utils/lang-utils'; import { getHTMLFromComponent } from '../../utils/react-utils'; import VersionIframe from '../VersionIframe'; +// Key of the merged nav-in-product-help.adoc entry in processedNavMap (pageid minus 'nav-' prefix). +// Not a real DocCategory/tab — used only to pick the left sidebar content when embedded in-product. +const IN_PRODUCT_NAV_KEY = 'in-product-help'; + const DevDocTemplate: FC = (props) => { const { data, @@ -127,21 +131,28 @@ const DevDocTemplate: FC = (props) => { []); // Breadcrumb data built from master nav + all category navs for full coverage + // (excludes the merged in-product nav, which duplicates the category navs) const breadcrumsData = React.useMemo(() => { if (typeof window === 'undefined') return []; const allHtmls = [ initialNavContentData, - ...Object.values(processedNavMap as Record), + ...Object.entries(processedNavMap as Record) + .filter(([cat]) => cat !== IN_PRODUCT_NAV_KEY) + .map(([, html]) => html), ]; return allHtmls.flatMap((html) => fetchChild(html)); }, [processedNavMap]); - // Pick the right sidebar content for the active category + // Pick the right sidebar content for the active category. + // In-product (embedded) presentation has no category tabs — always show the merged nav. const activeNavContent = React.useMemo(() => { + if (!isPublicSiteOpen) { + return processedNavMap[IN_PRODUCT_NAV_KEY] || navContent; + } const navId = CATEGORY_NAV_ID[activeCategory]; const mapKey = navId.startsWith('nav-') ? navId.slice(4) : null; return (mapKey && processedNavMap[mapKey]) || navContent; - }, [activeCategory, processedNavMap, navContent]); + }, [activeCategory, processedNavMap, navContent, isPublicSiteOpen]); const isCustomPage = _.values(CUSTOM_PAGE_ID).some( (pageId: string) => pageId === params[TS_PAGE_ID_PARAM], @@ -171,11 +182,13 @@ const isVersionedIframe = VERSION_DROPDOWN.some( const isAskDocsPage = params[TS_PAGE_ID_PARAM] === CUSTOM_PAGE_ID.ASK_DOCS; /* Build pageId → category map by parsing hrefs from each category's nav HTML. - * This means writers only need to update nav-*.adoc — no TypeScript changes needed. */ + * This means writers only need to update nav-*.adoc — no TypeScript changes needed. + * Excludes the merged in-product nav, which isn't a real tab/category. */ const pageIdToCategoryMap = React.useMemo(() => { if (typeof window === 'undefined') return {}; const map: Record = {}; Object.entries(processedNavMap).forEach(([cat, html]) => { + if (cat === IN_PRODUCT_NAV_KEY) return; const doc = new DOMParser().parseFromString(html as string, 'text/html'); doc.querySelectorAll('a[href]').forEach((a) => { const href = a.getAttribute('href') || ''; @@ -723,13 +736,28 @@ if (isVersionedIframe) { } > {!isIframeMode && !isVersionedIframe && ( - + isPublicSiteOpen ? ( + + ) : !isMaxMobileResolution && ( + // In-product presentation has no tabs — show just the nav + // toggle so the sidebar stays reachable on narrow viewports. + // Desktop-width embeds skip this entirely; the sidebar is + // always visible there. + + ) )}
diff --git a/src/components/LeftSidebar/NavContent.tsx b/src/components/LeftSidebar/NavContent.tsx index 7629d9022..f4fa1ea97 100644 --- a/src/components/LeftSidebar/NavContent.tsx +++ b/src/components/LeftSidebar/NavContent.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { navigate } from 'gatsby'; import { IconContext } from '@react-icons/all-files'; import { BiSearch } from '@react-icons/all-files/bi/BiSearch'; import BackButton from '../BackButton'; @@ -50,6 +51,19 @@ const NavContent = (props: { + {/* AskDocs lives in the top SecondaryHeader on the standalone site; + that bar is hidden in-product, so surface it here instead. */} + {!props.isPublicSiteOpen && ( +
+ +
+ )}