Update name in Wrangler configuration file to match deployed Worker#83
Open
cloudflare-workers-and-pages[bot] wants to merge 25 commits into
Open
Update name in Wrangler configuration file to match deployed Worker#83cloudflare-workers-and-pages[bot] wants to merge 25 commits into
cloudflare-workers-and-pages[bot] wants to merge 25 commits into
Conversation
3d3c015 to
388da4f
Compare
88d4fe3 to
b4ec319
Compare
b4ec319 to
08d0fa0
Compare
08d0fa0 to
0c6e4d3
Compare
0c6e4d3 to
a7aef80
Compare
a7aef80 to
c0128ad
Compare
c0128ad to
a0a5783
Compare
ef30848 to
4e1d978
Compare
- 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`
- 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>
a0a5783 to
8655f1f
Compare
8655f1f to
8abce48
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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