Skip to content

Update name in Wrangler configuration file to match deployed Worker#83

Open
cloudflare-workers-and-pages[bot] wants to merge 25 commits into
test-sbfrom
update_worker_name_to_test-sb
Open

Update name in Wrangler configuration file to match deployed Worker#83
cloudflare-workers-and-pages[bot] wants to merge 25 commits into
test-sbfrom
update_worker_name_to_test-sb

Conversation

@cloudflare-workers-and-pages
Copy link
Copy Markdown

The Worker name in your Wrangler configuration file does not match the name of the deployed Worker in the Cloudflare Dashboard.
Cloudflare automatically generated this PR to resolve the mismatch and avoid inconsistencies between environments. For more information, see: https://developers.cloudflare.com/workers/ci-cd/builds/troubleshoot/#workers-name-requirement

@cloudflare-workers-and-pages cloudflare-workers-and-pages Bot force-pushed the update_worker_name_to_test-sb branch from 3d3c015 to 388da4f Compare March 11, 2026 22:46
@cloudflare-workers-and-pages cloudflare-workers-and-pages Bot force-pushed the update_worker_name_to_test-sb branch 2 times, most recently from 88d4fe3 to b4ec319 Compare March 17, 2026 20:51
@cloudflare-workers-and-pages cloudflare-workers-and-pages Bot force-pushed the update_worker_name_to_test-sb branch from b4ec319 to 08d0fa0 Compare March 24, 2026 18:29
@cloudflare-workers-and-pages cloudflare-workers-and-pages Bot force-pushed the update_worker_name_to_test-sb branch from 08d0fa0 to 0c6e4d3 Compare March 24, 2026 18:39
@cloudflare-workers-and-pages cloudflare-workers-and-pages Bot force-pushed the update_worker_name_to_test-sb branch from 0c6e4d3 to a7aef80 Compare March 24, 2026 23:48
@cloudflare-workers-and-pages cloudflare-workers-and-pages Bot force-pushed the update_worker_name_to_test-sb branch from a7aef80 to c0128ad Compare March 25, 2026 00:00
@cloudflare-workers-and-pages cloudflare-workers-and-pages Bot force-pushed the update_worker_name_to_test-sb branch from c0128ad to a0a5783 Compare March 25, 2026 19:29
@ashubham ashubham force-pushed the test-sb branch 2 times, most recently from ef30848 to 4e1d978 Compare April 27, 2026 23:18
Rifdhan and others added 14 commits April 27, 2026 17:28
- Add new DO for conversation storage, and serve it on a new
  /storage/conversation-id route
- Add test coverage
- This DO is not yet used, we will switch to this in a future PR

Co-authored-by: Rifdhan Nazeer <rifdhan.nazeer@thoughtspot.com>
- Create a storage-service client for the new storage server DO
- Add test coverage
- Not used yet, will be used in a future PR

Co-authored-by: Rifdhan Nazeer <rifdhan.nazeer@thoughtspot.com>
- Each message will have a new is_thinking flag, indicating whether
  the message is part of Spotter's thinking process or final results
- Add test coverage
- Fix some minor biome formatter violations

Co-authored-by: Rifdhan Nazeer <rifdhan.nazeer@thoughtspot.com>
- Remove /storage public route and use internal binding to access
  Storage Server (no longer need to expose the endpoint publicly)
- Wire up Storage Client to use the new Storage Server in place of
  existing storage class
- Update tests

Co-authored-by: Rifdhan Nazeer <rifdhan.nazeer@thoughtspot.com>
* SCAL-308277 Add metrics recorder core

## Summary

Introduce the request-scoped metrics runtime core for the Worker and add
focused tests so the new runtime metrics files do not regress repo
coverage.

## What Changed

- add metric definitions, label normalization, and runtime config for sink
  selection
- add the request-scoped recorder, sink interfaces, composite/noop sinks,
  and context helpers
- wrap the Worker fetch entrypoint so every request gets a recorder and
  non-blocking flush behavior
- add targeted tests for metric context, sink behavior, recorder branches,
  runtime config, and request-scoped recorder helpers

## Notes

- this PR only adds the runtime core, request wrapper plumbing, and tests
- external Analytics Engine and Grafana emission lands in follow-up PRs

## Validation

- `npm test -- --coverage.enabled=false test/metrics/runtime`
- `npm test`

* SCAL-308277 Fix recorder flush race

## Summary

Close the recorder as soon as flush begins, add coverage for the in-flight
flush case, and address the follow-up lint and label-policy feedback.

## What Changed

- mark the recorder flushed before awaiting the sink and snapshot observations
  once
- add a test that rejects metrics recorded after flush has started
- document why forbidden metric label keys stay explicit
- remove the redundant `both` switch case flagged by Biome

## Validation

- `npm run lint`
- `npm test`

* Refine request metrics routing context

## Summary

Strip tracing headers before metrics setup and centralize route metric
classification so request metrics are easier to maintain as routes evolve.

## What Changed

- move tracing header stripping ahead of `withRequestMetrics(...)` in the
  Worker entrypoint
- replace duplicated metric path classification helpers with a shared explicit
  route-context table and resolver
- expand focused metric-context tests to cover the shared route metadata and
  fallback behavior

## Validation

- `npm run lint`
- `npm test -- --coverage.enabled=false test/metrics/runtime/metric-context.spec.ts test/index.header-stripping.spec.ts`

* SCAL-308277 Add production route metrics registry

Move known public routes into production-owned constants so metrics context coverage
stays tied to the routes served by the Worker.

- add shared route constants for exact routes and grouped prefixes
- use route constants in Worker, bearer, and Hono route registration
- key explicit metrics route contexts from production route constants
- add storage, OpenAI challenge, token/register, hello, and OpenAPI route groups
- allow the low-cardinality is_thinking stream update label
- cover route context registration and label normalization in tests

- `npm run lint`
- `npm test`

* SCAL-308277 Classify OpenAPI spec subroutes

## Summary

Classify mounted OpenAPI spec subroutes with the same route context as the
base `/openapi-spec` endpoint.

## What Changed

- add an OpenAPI spec route prefix constant
- map `/openapi-spec/*` to `route_group=openapi_spec`
- keep OpenAPI spec routes on the static, unauthenticated API surface
- cover generated tool spec paths in route context tests

## Validation

- `npm run lint`
- `npm test -- --coverage.enabled=false test/metrics/runtime/metric-context.spec.ts`
- `npm test`
- Each value has a maximum of 131072 bytes, and we are running
  into that limit in real world scenarios
- Instead of storing the full conversation in a single key, split
  each message into its own key, giving us much higher storage
- Update tests

Co-authored-by: Rifdhan Nazeer <rifdhan.nazeer@thoughtspot.com>
* SCAL-309983 Harden metrics request isolation

## Summary

Harden the metrics request wrapper so metrics setup, scheduling, and flush failures cannot
block MCP business logic or become visible to MCP clients.

## What Changed

- fall back to a noop sink if metrics config or sink construction throws
- keep `recorder.flush()` focused on metrics delivery, not Worker scheduling
- schedule request metrics flush through `ctx.waitUntil(...)` without awaiting delivery
- log waitUntil scheduling failures separately from metrics execution failures
- add tests for setup fallback, slow flushes, handler failures, waitUntil failures, and
  delivery failures

## Semantics

Direct `recorder.flush()` calls still await delivery. `withRequestMetrics(...)` only schedules
the request-scoped flush so slow, failing, or unavailable sinks do not delay responses.

Metrics failures remain best-effort side effects and are never propagated to MCP clients.

## Validation

- `npm run lint`
- focused runtime metrics tests
- `npm test`

* SCAL-309983 Return noop recorder on init fallback

## Summary

Use a stateless noop metrics recorder for initialization fallback so the fail-open path does
not construct a second request recorder.

## What Changed

- add a shared `NOOP_METRICS_RECORDER` implementation
- return the noop recorder when metrics config or sink setup throws
- update tests and log wording to reflect the recorder-level fallback
- If getSessionInfo call fails, handle the exception and log error
- Add test coverage

Co-authored-by: Rifdhan Nazeer <rifdhan.nazeer@thoughtspot.com>
## Summary

Make the nanoid integration tests independent of global `fetch` state so the full
Vitest run is stable.

## What Changed

- replace the module-level `global.fetch = vi.fn()` assignment with a per-test fetch mock
- stub and unstub `fetch` in `beforeEach` and `afterEach`
- keep the existing nanoid assertions unchanged while removing order dependence

## Validation

- `npm run lint`
- `npm test -- --coverage.enabled=false test/thoughtspot/thoughtspot-client-nanoid-integration.spec.ts`
- `npm test`
- Add new entry in version registry for 2026-05-01
- Add new "latest" version option, mapping to newest available
  non-beta version
- Remove "default" version, default will now be latest
- Add "backwards-compatibility-default" version which points to
  older version for now, will be removed in the future
- Add metrics tracking of versioning
- Update tests

Co-authored-by: Rifdhan Nazeer <rifdhan.nazeer@thoughtspot.com>
Co-authored-by: Rifdhan Nazeer <rifdhan.nazeer@thoughtspot.com>
* SCAL-308279 Add Grafana OTLP metrics sink

Add the direct Grafana OTLP/HTTP sink for low-cardinality MCP service metrics.
This keeps PR 3 independent from the Analytics Engine sink so it can be
reviewed and merged in parallel.

- add a Grafana OTLP metrics sink that emits OTLP JSON over HTTP
- convert counters, gauges, and histograms into OTLP metric datapoints
- normalize OTLP endpoints to `/v1/metrics`
- support Grafana Cloud Basic auth and explicit OTLP auth headers
- wire request metrics to build the Grafana sink from env config
- test payload mapping, endpoint config, auth headers, and failure behavior

The sink sends delta sums and histograms because request-scoped observations
are emitted as per-flush deltas. Export failures are surfaced to the recorder,
where the existing metrics flush isolation logs and drops them without changing
business responses.

- `npm run lint`
- focused runtime metrics tests for Grafana sink and request metrics

* SCAL-308279 Aggregate OTLP metric datapoints

## Summary

Address review feedback for the Grafana OTLP payload shape and timestamp precision.
OTLP requires each metric to contain at most one datapoint for a given attribute set.

## What Changed

- aggregate same-metric and same-label observations before creating OTLP datapoints
- sum counters and histogram count, sum, and bucket counts per attribute set
- keep the latest gauge value per attribute set
- convert millisecond timestamps to nanoseconds with `BigInt` precision
- add regression coverage for duplicate attributes and fractional millisecond timestamps

## Validation

- `npm run lint`
- focused runtime metrics tests
- `npm test`

* SCAL-308279 Avoid counter bucket allocation

## Summary

Avoid allocating histogram bucket storage for non-histogram OTLP datapoints.

## Validation

- `npm run lint`
- `npm test -- --coverage.enabled=false test/metrics/runtime/grafana-otlp-sink.spec.ts`

* SCAL-308279 Harden OTLP auth and timestamps

## Summary

Address Grafana OTLP review feedback for Basic auth encoding, timestamp conversion,
and export error messages.

## What Changed

- encode Basic auth input as UTF-8 before base64 conversion when Buffer is unavailable
- split millisecond timestamps into integer and fractional parts before BigInt conversion
- keep timestamp export at microsecond precision to avoid unsafe epoch-scale float math
- cap Grafana OTLP export error bodies included in exception messages
- add regression coverage for non-ASCII credentials and large export error bodies

## Notes

The attribute aggregation key remains JSON-based because request-scoped flushes are small and
attributes are already sorted, making the key stable. A cheaper custom key can be added later if
this sink is reused for high-volume background aggregation.

## Validation

- `npm run lint`
- focused runtime metrics tests

* SCAL-308279 Cache Grafana OTLP sink per env

Avoid rebuilding the default Grafana OTLP sink for every request in a warm Worker isolate.

- add a module-level WeakMap keyed by the Worker env object
- reuse the Grafana sink for repeated recorder creation with the same env
- keep caller-provided sinks unchanged for tests and explicit injection
- add coverage for same-env cache reuse

The cache is opportunistic and per Worker isolate. It does not provide correctness guarantees,
and cold starts or new isolates will rebuild the sink.

- `npm run lint`
- focused runtime metrics tests

* SCAL-308279 Avoid histogram bucket copies

## Summary

Avoid per-observation histogram bucket array allocation during OTLP aggregation.

## What Changed

- replace per-observation bucket count arrays with a bucket-index helper
- increment the target aggregate bucket directly
- preserve existing histogram aggregation semantics

## Validation

- `npm run lint`
- focused runtime metrics tests

* SCAL-308279 Refine OTLP timestamp and helper naming

## Summary

Tighten the Grafana OTLP sink helpers around timestamp conversion, naming clarity, and
error-body truncation.

## What Changed

- rename OTLP attribute and authorization helper functions for clearer intent
- remove redundant string unions from OTLP attribute helper types
- convert fractional millisecond timestamps directly to nanoseconds with carry handling
- enforce the export error-body length limit including the trailing ellipsis
- add regression coverage for fractional-millisecond precision and truncation behavior

## Validation

-
> @thoughtspot/mcp-server@0.5.0 lint
> biome lint

Checked 72 files in 44ms. No fixes applied.
-
> @thoughtspot/mcp-server@0.5.0 test
> vitest run --coverage.enabled=false test/metrics/runtime/grafana-otlp-sink.spec.ts test/metrics/runtime/request-metrics.spec.ts test/metrics/runtime/runtime-config.spec.ts test/metrics/runtime/sinks.spec.ts

 RUN  v3.2.4 /Users/kanwarbir.bajwa/mcp-server

[vpw:info] Starting single runtime for vitest.config.ts...
 ✓ test/metrics/runtime/request-metrics.spec.ts (12 tests) 8ms
 ✓ test/metrics/runtime/runtime-config.spec.ts (9 tests) 2ms
 ✓ test/metrics/runtime/grafana-otlp-sink.spec.ts (12 tests) 3ms
 ✓ test/metrics/runtime/sinks.spec.ts (3 tests) 1ms

 Test Files  4 passed (4)
      Tests  36 passed (36)
   Start at  09:19:17
   Duration  1.43s (transform 193ms, setup 124ms, collect 85ms, tests 14ms, environment 0ms, prepare 253ms)

[vpw:debug] Shutting down runtimes...
-
> @thoughtspot/mcp-server@0.5.0 test
> vitest run

 RUN  v3.2.4 /Users/kanwarbir.bajwa/mcp-server
      Coverage enabled with istanbul

[vpw:info] Starting single runtime for vitest.config.ts...
 ✓ test/index.header-stripping.spec.ts (5 tests) 2473ms
   ✓ Header stripping > strips traceparent before the request reaches the OAuth provider  527ms
   ✓ Header stripping > strips tracestate before the request reaches the OAuth provider  499ms
   ✓ Header stripping > strips all tracing headers while preserving others  487ms
   ✓ Header stripping > does not mutate the original request object  478ms
   ✓ Header stripping > passes the request through unchanged when no tracing headers are present  479ms
 ✓ test/index.spec.ts (4 tests) 1947ms
   ✓ The ThoughtSpot MCP Worker: Auth handler > responds with Hello World! on '/hello'  488ms
   ✓ MCP Router with API Version > should create router with correct serve method for /mcp  478ms
   ✓ MCP Router with API Version > should create router with correct serve method for /sse  496ms
   ✓ MCP Router with API Version > should handle query parameters in router paths  484ms
stdout | test/servers/mcp-server.spec.ts > MCP Server > Get Relevant Questions Tool > should return relevant questions for a query
[DEBUG] Getting relevant questions for datasource:  [ 'ds-123', 'ds-456' ]
[DEBUG] Getting relevant questions with datasource:  [ 'ds-123', 'ds-456' ]

stdout | test/servers/mcp-server.spec.ts > MCP Server > Get Relevant Questions Tool > should handle error from service
[DEBUG] Getting relevant questions for datasource:  [ 'ds-123' ]
[DEBUG] Getting relevant questions with datasource:  [ 'ds-123' ]

stdout | test/servers/mcp-server.spec.ts > MCP Server > Get Relevant Questions Tool > should handle error from service with multiple datasource IDs
[DEBUG] Getting relevant questions for datasource:  [ 'ds-123', 'ds-456', 'ds-789' ]
[DEBUG] Getting relevant questions with datasource:  [ 'ds-123', 'ds-456', 'ds-789' ]

stdout | test/servers/mcp-server.spec.ts > MCP Server > Get Relevant Questions Tool > should handle error from service with empty datasourceIds array
[DEBUG] Getting relevant questions for datasource:  []
[DEBUG] Getting relevant questions with datasource:  []

stdout | test/servers/mcp-server.spec.ts > MCP Server > Get Relevant Questions Tool > should handle empty questions response
[DEBUG] Getting relevant questions for datasource:  [ 'ds-123' ]
[DEBUG] Getting relevant questions with datasource:  [ 'ds-123' ]

stdout | test/servers/mcp-server.spec.ts > MCP Server > Get Relevant Questions Tool > should handle optional additional context
[DEBUG] Getting relevant questions for datasource:  [ 'ds-123' ]
[DEBUG] Getting relevant questions with datasource:  [ 'ds-123' ]

stdout | test/servers/mcp-server.spec.ts > MCP Server > Get Answer Tool > should return answer for a question
[DEBUG] Getting answer for sourceId:  ds-123 shouldGetTML:  false

stdout | test/servers/mcp-server.spec.ts > MCP Server > Get Answer Tool > should return answer for a question
[DEBUG] Getting Data for session_identifier:  session-123 generation_number:  1 instanceUrl:  https://test.thoughtspot.cloud

stdout | test/servers/mcp-server.spec.ts > MCP Server > Get Answer Tool > should handle error from service
[DEBUG] Getting answer for sourceId:  ds-123 shouldGetTML:  false

stdout | test/servers/mcp-server.spec.ts > MCP Server > Create Liveboard Tool > should create liveboard successfully
[DEBUG] Getting TML for answer:  What is the total revenue?

stdout | test/servers/mcp-server.spec.ts > MCP Server > Create Liveboard Tool > should handle error from service
[DEBUG] Getting TML for answer:  What is the total revenue?

 ✓ test/servers/mcp-server.spec.ts (36 tests) 79ms
stdout | test/handlers.spec.ts > Handlers > POST /authorize > Instance URL regex pattern matching > should NOT redirect to callback for URLs that don't match the pattern
redirectUrl https://company.thoughtspot.cloud/callosum/v1/saml/login?targetURLPath=https%3A%2F%2Fexample.com%2Fcallback%3FinstanceUrl%3Dhttps%253A%252F%252Fcompany.thoughtspot.cloud%26oauthReqInfo%3DeyJjbGllbnRJZCI6InRlc3QifQ%253D%253D

stdout | test/handlers.spec.ts > Handlers > POST /authorize > Instance URL regex pattern matching > should NOT redirect to callback for URLs that don't match the pattern
redirectUrl https://team.thoughtspot.cloud/callosum/v1/saml/login?targetURLPath=https%3A%2F%2Fexample.com%2Fcallback%3FinstanceUrl%3Dhttps%253A%252F%252Fteam.thoughtspot.cloud%26oauthReqInfo%3DeyJjbGllbnRJZCI6InRlc3QifQ%253D%253D

stdout | test/handlers.spec.ts > Handlers > POST /authorize > Instance URL regex pattern matching > should NOT redirect to callback for URLs that don't match the pattern
redirectUrl https://my.thoughtspot.cloud/callosum/v1/saml/login?targetURLPath=https%3A%2F%2Fexample.com%2Fcallback%3FinstanceUrl%3Dhttps%253A%252F%252Fmy.thoughtspot.cloud%26oauthReqInfo%3DeyJjbGllbnRJZCI6InRlc3QifQ%253D%253D

stdout | test/handlers.spec.ts > Handlers > POST /authorize > Instance URL regex pattern matching > should NOT redirect to callback for URLs that don't match the pattern
redirectUrl https://teamabc.thoughtspot.cloud/callosum/v1/saml/login?targetURLPath=https%3A%2F%2Fexample.com%2Fcallback%3FinstanceUrl%3Dhttps%253A%252F%252Fteamabc.thoughtspot.cloud%26oauthReqInfo%3DeyJjbGllbnRJZCI6InRlc3QifQ%253D%253D

stdout | test/handlers.spec.ts > Handlers > POST /authorize > Instance URL regex pattern matching > should NOT redirect to callback for URLs that don't match the pattern
redirectUrl https://myabc.thoughtspot.cloud/callosum/v1/saml/login?targetURLPath=https%3A%2F%2Fexample.com%2Fcallback%3FinstanceUrl%3Dhttps%253A%252F%252Fmyabc.thoughtspot.cloud%26oauthReqInfo%3DeyJjbGllbnRJZCI6InRlc3QifQ%253D%253D

stdout | test/handlers.spec.ts > Handlers > POST /authorize > Instance URL regex pattern matching > should NOT redirect to callback for URLs that don't match the pattern
redirectUrl https://team1test.thoughtspot.cloud/callosum/v1/saml/login?targetURLPath=https%3A%2F%2Fexample.com%2Fcallback%3FinstanceUrl%3Dhttps%253A%252F%252Fteam1test.thoughtspot.cloud%26oauthReqInfo%3DeyJjbGllbnRJZCI6InRlc3QifQ%253D%253D

stdout | test/handlers.spec.ts > Handlers > POST /authorize > Instance URL regex pattern matching > should NOT redirect to callback for URLs that don't match the pattern
redirectUrl https://my1test.thoughtspot.cloud/callosum/v1/saml/login?targetURLPath=https%3A%2F%2Fexample.com%2Fcallback%3FinstanceUrl%3Dhttps%253A%252F%252Fmy1test.thoughtspot.cloud%26oauthReqInfo%3DeyJjbGllbnRJZCI6InRlc3QifQ%253D%253D

stdout | test/handlers.spec.ts > Handlers > POST /authorize > Instance URL regex pattern matching > should NOT redirect to callback for URLs that don't match the pattern
redirectUrl https://test-team1.thoughtspot.cloud/callosum/v1/saml/login?targetURLPath=https%3A%2F%2Fexample.com%2Fcallback%3FinstanceUrl%3Dhttps%253A%252F%252Ftest-team1.thoughtspot.cloud%26oauthReqInfo%3DeyJjbGllbnRJZCI6InRlc3QifQ%253D%253D

stdout | test/handlers.spec.ts > Handlers > POST /authorize > Instance URL regex pattern matching > should NOT redirect to callback for URLs that don't match the pattern
redirectUrl https://test-my1.thoughtspot.cloud/callosum/v1/saml/login?targetURLPath=https%3A%2F%2Fexample.com%2Fcallback%3FinstanceUrl%3Dhttps%253A%252F%252Ftest-my1.thoughtspot.cloud%26oauthReqInfo%3DeyJjbGllbnRJZCI6InRlc3QifQ%253D%253D

stdout | test/handlers.spec.ts > Handlers > POST /authorize > Instance URL regex pattern matching > should NOT redirect to callback for URLs that don't match the pattern
redirectUrl https://team1.test.cloud/callosum/v1/saml/login?targetURLPath=https%3A%2F%2Fexample.com%2Fcallback%3FinstanceUrl%3Dhttps%253A%252F%252Fteam1.test.cloud%26oauthReqInfo%3DeyJjbGllbnRJZCI6InRlc3QifQ%253D%253D

stdout | test/handlers.spec.ts > Handlers > POST /authorize > Instance URL regex pattern matching > should NOT redirect to callback for URLs that don't match the pattern
redirectUrl https://my1.test.cloud/callosum/v1/saml/login?targetURLPath=https%3A%2F%2Fexample.com%2Fcallback%3FinstanceUrl%3Dhttps%253A%252F%252Fmy1.test.cloud%26oauthReqInfo%3DeyJjbGllbnRJZCI6InRlc3QifQ%253D%253D

stdout | test/handlers.spec.ts > Handlers > POST /authorize > Instance URL regex pattern matching > should NOT redirect to callback for URLs that don't match the pattern
redirectUrl https://team123.thoughtspot.com/callosum/v1/saml/login?targetURLPath=https%3A%2F%2Fexample.com%2Fcallback%3FinstanceUrl%3Dhttps%253A%252F%252Fteam123.thoughtspot.com%26oauthReqInfo%3DeyJjbGllbnRJZCI6InRlc3QifQ%253D%253D

stdout | test/handlers.spec.ts > Handlers > POST /authorize > Instance URL regex pattern matching > should NOT redirect to callback for URLs that don't match the pattern
redirectUrl https://my123.thoughtspot.com/callosum/v1/saml/login?targetURLPath=https%3A%2F%2Fexample.com%2Fcallback%3FinstanceUrl%3Dhttps%253A%252F%252Fmy123.thoughtspot.com%26oauthReqInfo%3DeyJjbGllbnRJZCI6InRlc3QifQ%253D%253D

stdout | test/handlers.spec.ts > Handlers > POST /authorize > Instance URL regex pattern matching > should NOT redirect to callback for URLs that don't match the pattern
redirectUrl http://team1.thoughtspot.cloud/callosum/v1/saml/login?targetURLPath=https%3A%2F%2Fexample.com%2Fcallback%3FinstanceUrl%3Dhttp%253A%252F%252Fteam1.thoughtspot.cloud%26oauthReqInfo%3DeyJjbGllbnRJZCI6InRlc3QifQ%253D%253D

stdout | test/handlers.spec.ts > Handlers > POST /authorize > Instance URL regex pattern matching > should NOT redirect to callback for URLs that don't match the pattern
redirectUrl http://my1.thoughtspot.cloud/callosum/v1/saml/login?targetURLPath=https%3A%2F%2Fexample.com%2Fcallback%3FinstanceUrl%3Dhttp%253A%252F%252Fmy1.thoughtspot.cloud%26oauthReqInfo%3DeyJjbGllbnRJZCI6InRlc3QifQ%253D%253D

 ✓ test/handlers.spec.ts (34 tests | 5 skipped) 45ms
 ✓ test/thoughtspot/thoughtspot-client.spec.ts (37 tests) 21ms
 ✓ test/metrics/mixpanel/mixpanel-tracker.spec.ts (25 tests) 27ms
 ✓ test/utils.spec.ts (41 tests) 20ms
 ✓ test/streaming-utils.spec.ts (17 tests) 11ms
 ✓ test/metrics/mixpanel/integration.spec.ts (13 tests) 10ms
 ✓ test/servers/openai-mcp-server.spec.ts (19 tests) 10ms
 ✓ test/storage-service/storage-service.spec.ts (17 tests) 10ms
 ✓ test/metrics/mixpanel/mixpanel-client.spec.ts (21 tests) 9ms
 ✓ test/thoughtspot/thoughtspot-client-nanoid-integration.spec.ts (6 tests) 6ms
 ✓ test/metrics/tracing/tracing-utils.spec.ts (17 tests) 9ms
 ✓ test/servers/conversation-storage-server.spec.ts (25 tests) 7ms
 ✓ test/servers/mcp-server-base.spec.ts (15 tests) 8ms
 ✓ test/metrics/runtime/request-metrics.spec.ts (12 tests) 11ms
 ✓ test/bearer.spec.ts (36 tests) 7ms
 ✓ test/servers/api-server.spec.ts (13 tests) 10ms
stdout | test/thoughtspot/thoughtspot-service.spec.ts > thoughtspot-service > getRelevantQuestions > should return relevant questions successfully
[DEBUG] Getting relevant questions with datasource:  [ 'ws1', 'ws2' ]

stdout | test/thoughtspot/thoughtspot-service.spec.ts > thoughtspot-service > getRelevantQuestions > should handle empty additional context
[DEBUG] Getting relevant questions with datasource:  [ 'ws1' ]

stdout | test/thoughtspot/thoughtspot-service.spec.ts > thoughtspot-service > getRelevantQuestions > should handle null additional context
[DEBUG] Getting relevant questions with datasource:  [ 'ws1' ]

stdout | test/thoughtspot/thoughtspot-service.spec.ts > thoughtspot-service > getRelevantQuestions > should handle missing decomposedQueryResponse
[DEBUG] Getting relevant questions with datasource:  [ 'ws1' ]

stdout | test/thoughtspot/thoughtspot-service.spec.ts > thoughtspot-service > getRelevantQuestions > should handle API errors
[DEBUG] Getting relevant questions with datasource:  [ 'ws1' ]

stdout | test/thoughtspot/thoughtspot-service.spec.ts > thoughtspot-service > getAnswerForQuestion > should return answer data successfully without TML
[DEBUG] Getting answer for sourceId:  ws1 shouldGetTML:  false

stdout | test/thoughtspot/thoughtspot-service.spec.ts > thoughtspot-service > getAnswerForQuestion > should return answer data successfully without TML
[DEBUG] Getting Data for session_identifier:  session123 generation_number:  1 instanceUrl:  https://test.thoughtspot.com

stdout | test/thoughtspot/thoughtspot-service.spec.ts > thoughtspot-service > getAnswerForQuestion > should return answer data with TML when requested
[DEBUG] Getting answer for sourceId:  ws1 shouldGetTML:  true

stdout | test/thoughtspot/thoughtspot-service.spec.ts > thoughtspot-service > getAnswerForQuestion > should return answer data with TML when requested
[DEBUG] Getting Data for session_identifier:  session123 generation_number:  1 instanceUrl:  https://test.thoughtspot.com
[DEBUG] Getting TML for answer:  What is the revenue?

stdout | test/thoughtspot/thoughtspot-service.spec.ts > thoughtspot-service > getAnswerForQuestion > should limit CSV data to 100 lines
[DEBUG] Getting answer for sourceId:  ws1 shouldGetTML:  false

stdout | test/thoughtspot/thoughtspot-service.spec.ts > thoughtspot-service > getAnswerForQuestion > should limit CSV data to 100 lines
[DEBUG] Getting Data for session_identifier:  session123 generation_number:  1 instanceUrl:  https://test.thoughtspot.com

stdout | test/thoughtspot/thoughtspot-service.spec.ts > thoughtspot-service > getAnswerForQuestion > should handle TML export errors gracefully
[DEBUG] Getting answer for sourceId:  ws1 shouldGetTML:  true

stdout | test/thoughtspot/thoughtspot-service.spec.ts > thoughtspot-service > getAnswerForQuestion > should handle TML export errors gracefully
[DEBUG] Getting Data for session_identifier:  session123 generation_number:  1 instanceUrl:  https://test.thoughtspot.com
[DEBUG] Getting TML for answer:  What is the revenue?

stdout | test/thoughtspot/thoughtspot-service.spec.ts > thoughtspot-service > getAnswerForQuestion > should handle API errors
[DEBUG] Getting answer for sourceId:  ws1 shouldGetTML:  false

stdout | test/thoughtspot/thoughtspot-service.spec.ts > thoughtspot-service > fetchTMLAndCreateLiveboard > should fetch TML and create liveboard successfully
[DEBUG] Getting TML for answer:  undefined
[DEBUG] Getting TML for answer:  undefined

stdout | test/thoughtspot/thoughtspot-service.spec.ts > thoughtspot-service > fetchTMLAndCreateLiveboard > should handle TML fetch errors
[DEBUG] Getting TML for answer:  undefined

 ✓ test/thoughtspot/thoughtspot-service.spec.ts (46 tests) 14ms
 ✓ test/oauth-manager/oauth-utils.spec.ts (20 tests) 5ms
 ✓ test/oauth-manager/token-utils.integration.spec.ts (12 tests) 6ms
 ✓ test/oauth-manager/token-utils.spec.ts (16 tests) 4ms
 ✓ test/streaming-message-storage-with-ttl/streaming-message-storage-with-ttl.spec.ts (27 tests) 4ms
 ✓ test/metrics/runtime/grafana-otlp-sink.spec.ts (12 tests) 2ms
 ✓ test/servers/version-registry.spec.ts (39 tests) 2ms
 ✓ test/metrics/runtime/metric-context.spec.ts (8 tests) 1ms
 ✓ test/metrics/runtime/runtime-config.spec.ts (9 tests) 9ms
 ✓ test/metrics/runtime/metric-types.spec.ts (2 tests)
 ✓ test/metrics/runtime/metrics-recorder.spec.ts (8 tests) 1ms
 ✓ test/metrics/runtime/sinks.spec.ts (3 tests) 1ms

 Test Files  31 passed (31)
      Tests  590 passed | 5 skipped (595)
   Start at  09:19:19
   Duration  13.73s (transform 1.06s, setup 87ms, collect 6.35s, tests 4.77s, environment 0ms, prepare 100ms)

 % Coverage report from istanbul
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-------------------|---------|----------|---------|---------|-------------------
All files          |   89.24 |    84.47 |   90.24 |   89.34 |
 src               |   83.76 |    82.51 |   73.33 |   83.93 |
  bearer.ts        |     100 |      100 |     100 |     100 |
  ...lare-utils.ts |   35.29 |        0 |    37.5 |   35.29 | 39-84
  handlers.ts      |   93.22 |    79.59 |    92.3 |   93.22 | ...68,300,329,334
  index.ts         |   74.07 |       50 |      75 |      72 | 23,53-66
  routes.ts        |     100 |      100 |     100 |     100 |
  stdio.ts         |       0 |        0 |       0 |       0 | 9-55
  ...ming-utils.ts |     100 |    96.96 |     100 |     100 | 139
  utils.ts         |      90 |    96.29 |     100 |    92.3 | 110,128-129
 src/metrics       |     100 |      100 |     100 |     100 |
  index.ts         |     100 |      100 |     100 |     100 |
 ...trics/mixpanel |     100 |      100 |     100 |     100 |
  ...nel-client.ts |     100 |      100 |     100 |     100 |
  mixpanel.ts      |     100 |      100 |     100 |     100 |
 ...etrics/runtime |   91.97 |    89.61 |      96 |   91.95 |
  ...osite-sink.ts |     100 |      100 |     100 |     100 |
  ...-otlp-sink.ts |    87.2 |    78.57 |     100 |   87.09 | ...76,181,184,197
  ...ic-context.ts |   92.85 |       95 |     100 |   92.85 | 170,189,198,229
  metric-types.ts  |   96.87 |    94.11 |     100 |   96.87 | 86
  ...s-recorder.ts |     100 |      100 |   84.61 |     100 |
  noop-sink.ts     |       0 |        0 |       0 |       0 |
  ...st-metrics.ts |   91.66 |      100 |   88.88 |   91.66 | 104-108
  ...ime-config.ts |   94.44 |    89.18 |     100 |   94.44 | 22,39
 ...etrics/tracing |     100 |      100 |     100 |     100 |
  tracing-utils.ts |     100 |      100 |     100 |     100 |
 src/oauth-manager |   98.59 |       90 |     100 |   98.59 |
  oauth-utils.ts   |      98 |       85 |     100 |      98 | 451
  token-utils.ts   |     100 |      100 |     100 |     100 |
 src/servers       |    84.4 |    74.19 |   87.95 |   84.61 |
  api-server.ts    |   92.18 |     37.5 |   93.33 |   92.18 | 158-165
  ...age-server.ts |   98.52 |    83.78 |     100 |   98.52 | 182
  ...erver-base.ts |   88.88 |    66.66 |   86.36 |   88.88 | 75-78,178,255-257
  mcp-server.ts    |   65.94 |    72.13 |   77.27 |   65.92 | ...49-395,406-446
  ...mcp-server.ts |   86.95 |    70.58 |   88.88 |   88.63 | 151-167
  ...efinitions.ts |     100 |      100 |     100 |     100 |
  ...n-registry.ts |   90.32 |    83.33 |     100 |      90 | 57-60
 ...torage-service |     100 |      100 |     100 |     100 |
  ...ge-service.ts |     100 |      100 |     100 |     100 |
 ...orage-with-ttl |     100 |    94.44 |     100 |     100 |
  ...e-with-ttl.ts |     100 |    94.44 |     100 |     100 | 96
 src/thoughtspot   |   94.26 |    85.41 |   93.61 |   94.21 |
  ...pot-client.ts |   98.38 |      100 |   92.85 |   98.38 | 23
  ...ot-service.ts |   92.85 |    79.41 |   93.93 |   92.77 | ...98-208,647-652
-------------------|---------|----------|---------|---------|-------------------
[vpw:debug] Shutting down runtimes...

* SCAL-308279 Simplify Grafana OTLP env config

## Summary

Reduce the Grafana OTLP sink to one canonical env name per setting so the config
surface is explicit and easier to maintain.

## What Changed

- collapse Grafana OTLP config resolution to `GRAFANA_OTLP_*` env names only
- remove alias-based precedence across Grafana Cloud and OTLP-style env names
- drop `OTEL_EXPORTER_OTLP_HEADERS` parsing from the sink config path
- update Grafana sink tests to cover only the canonical env names

## Validation

- `npm run lint`
- `npm test -- --coverage.enabled=false test/metrics/runtime/grafana-otlp-sink.spec.ts test/metrics/runtime/request-metrics.spec.ts test/metrics/runtime/runtime-config.spec.ts test/metrics/runtime/sinks.spec.ts`
* SCAL-308278 Add Analytics Engine metrics sink

Add the Analytics Engine sink for the metrics runtime so PM and tenant event
observations can be written to the existing Cloudflare `ANALYTICS` binding.

- add an Analytics Engine sink that writes one datapoint per metric observation
- define the positional Analytics Engine schema for indexes, blobs, and doubles
- classify metric names into stable event families for PM-oriented querying
- wire request metrics to use `env.ANALYTICS` when the analytics sink is enabled
- keep missing bindings as noop through the existing sink selection path
- cover datapoint mapping, binding detection, and default sink wiring in tests

The schema reserves index positions for tenant and user identity. This PR wires
the sink and raw event shape; later instrumentation PRs will populate those
identity fields from ThoughtSpot session context where available.

- `npm run lint`
- `npm test -- --coverage.enabled=false test/metrics/runtime/analytics-engine-sink.spec.ts test/metrics/runtime/request-metrics.spec.ts test/metrics/runtime/runtime-config.spec.ts test/metrics/runtime/sinks.spec.ts`
- `npm test`

* SCAL-308278 Cover all Analytics Engine metric families

## Summary

Make Analytics Engine metric family classification exhaustive and cover all
current metric names in tests.

## What Changed

- map `sessionsStartedTotal` into the auth event family
- add an exhaustive check for future metric additions
- verify every `METRIC_NAMES` value resolves to a valid Analytics Engine family

## Validation

- `npm run lint`
- `npm test -- --coverage.enabled=false test/metrics/runtime/analytics-engine-sink.spec.ts`

* SCAL-308278 Isolate Analytics Engine write failures

## Summary

Keep one failed Analytics Engine write from aborting the rest of a metrics flush.

## What Changed

- allow Analytics Engine bindings to return either sync or async write results
- await each data point write during flush
- catch and warn per failed data point before continuing with the batch
- add regression coverage for continuing after a rejected write

## Validation

- `npm run lint`
- focused runtime metrics tests

* SCAL-308278 Parallelize Analytics Engine writes

## Summary

Write Analytics Engine metric datapoints in parallel during flush while keeping
per-point failure isolation.

## Validation

- `npm run lint`
- focused runtime metrics tests

* SCAL-308278 Add Analytics Engine event identity

## Summary

Make the future tenant/user enrichment path explicit in the metrics flush contract.

## What Changed

- add optional event identity to `MetricsFlushPayload`
- pass event identity into Analytics Engine data point conversion
- map tenant and user identity into Analytics Engine indexes when present
- add regression coverage for identity-backed Analytics Engine indexes

## Validation

- `npm run lint`
- focused runtime metrics tests

* SCAL-308278 Use sync Analytics Engine writes

## Summary

Match the Analytics Engine sink to Cloudflare's synchronous `writeDataPoint` API.

## What Changed

- narrow the Analytics Engine dataset contract back to synchronous `void`
- use a simple `for...of` loop with per-point error isolation
- update the failure-isolation test to throw synchronously

## Validation

- `npm run lint`
- focused runtime metrics tests

* SCAL-308278 Centralize Analytics Engine schema guards

## Summary

Tighten the Analytics Engine sink schema wiring so the dataset boundary is typed
explicitly and schema drift is caught by tests.

## What Changed

- add a dedicated `isAnalyticsEngineDatasetLike(...)` type guard for the binding
- derive persisted Analytics Engine label fields from `APPROVED_METRIC_LABEL_KEYS`
- centralize the persisted resource attribute field mapping used by the AE sink
- add a guard test that locks the AE schema arrays to the approved labels and
  resource attributes

## Validation

- `npm run lint`
- `npm test -- --coverage.enabled=false test/metrics/runtime/analytics-engine-sink.spec.ts test/metrics/runtime/request-metrics.spec.ts test/metrics/runtime/runtime-config.spec.ts test/metrics/runtime/sinks.spec.ts`
Rifdhan and others added 10 commits May 5, 2026 12:34
- Use a single transaction where possible for reading and writing
  multiple fields, to improve performance and consistency
- Update tests

Co-authored-by: Rifdhan Nazeer <rifdhan.nazeer@thoughtspot.com>
* SCAL-308280 Instrument request and auth health metrics

## Summary

Add the request-layer metrics for SCAL-308280 so MCP traffic and auth flows
emit bounded counters and latency through the shared runtime recorder.

## What Changed

- record ts_mcp_http_requests_total and ts_mcp_http_request_duration_ms at the worker edge with route, transport, auth mode, api surface, outcome, status class, and canonical api version labels
- add helpers to resolve bounded api_version values through the version registry instead of copying raw query params
- emit auth outcome counters for /authorize, /callback, /store-token, and /bearer/* / /token/* requests
- add focused tests for request metric labeling and auth metric emission
- include the small metrics-runtime review nits from PR #126 while touching the same files

## Notes

- ts_mcp_http_inflight_requests remains intentionally unimplemented because the current request-scoped recorder cannot represent a real inflight gauge safely

## Validation

- npm run lint -- src/index.ts src/bearer.ts src/handlers.ts src/metrics/runtime/request-metrics.ts src/metrics/runtime/grafana-otlp-sink.ts test/metrics/runtime/request-metrics.spec.ts test/bearer.spec.ts test/handlers.spec.ts
- npm test -- --coverage.enabled false test/metrics/runtime/request-metrics.spec.ts test/bearer.spec.ts test/handlers.spec.ts

* SCAL-308280 Fix API version labels in request metrics

## Summary

- map resolved API versions to stable low-cardinality labels
- reuse the parsed request URL in bearer auth handling
- add coverage for date-based API version label mapping
- Delete relevant code and update tests

Co-authored-by: Rifdhan Nazeer <rifdhan.nazeer@thoughtspot.com>
- Clean up a few leftover types

Co-authored-by: Rifdhan Nazeer <rifdhan.nazeer@thoughtspot.com>
## Summary

Fix the Workers Analytics Engine payload so production writes succeed again.

Cloudflare only accepts a single index per data point. The current sink writes
five indexes, which causes every Analytics Engine write to fail in production.

## What Changed

- switch the Analytics Engine sink to a compact AE-specific row layout with one
  tenant-scoped index and a bounded blob set
- keep is_done, drop is_thinking, and add analytical_session_id as
  Analytics-Engine-only context for session debugging
- propagate analyticalSessionId through the metrics context and attach it to the
  session creation and send-session-message tool flows
- update sink, recorder, request, MCP server, and ThoughtSpot service tests to
  lock the new schema

## Notes

- keep mcp_metrics_v2; production writes were failing, so this becomes the
  first valid persisted layout rather than a new version bump
- local design docs were updated for reference only and are not part of this
  repo commit
- Add coverage for new tools and related functions
- Increase min coverage level to 85% for all metrics

Co-authored-by: Rifdhan Nazeer <rifdhan.nazeer@thoughtspot.com>
Co-authored-by: Mourya Balabhadra <162541770+mouryabalabhadra@users.noreply.github.com>
- No implementation change required

Co-authored-by: Rifdhan Nazeer <rifdhan.nazeer@thoughtspot.com>
Co-authored-by: Rifdhan Nazeer <rifdhan.nazeer@thoughtspot.com>
@cloudflare-workers-and-pages cloudflare-workers-and-pages Bot force-pushed the update_worker_name_to_test-sb branch from a0a5783 to 8655f1f Compare May 7, 2026 22:15
@cloudflare-workers-and-pages cloudflare-workers-and-pages Bot force-pushed the update_worker_name_to_test-sb branch from 8655f1f to 8abce48 Compare May 7, 2026 22:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants