@meistrari/tela-sdk-js 2.3.0 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -171,12 +171,13 @@ execution.on('statusChange', (status) => {
171
171
 
172
172
  // Listen for polling updates
173
173
  execution.on('poll', (pollResult) => {
174
- console.log(`Poll - Status: ${pollResult.status}`)
174
+ console.log(`Poll - Status: ${pollResult.status}, Request ID: ${pollResult.requestId}`)
175
175
  })
176
176
 
177
177
  // Listen for successful completion
178
178
  execution.on('success', (result) => {
179
179
  console.log('Success!', result)
180
+ console.log('Request ID:', result.requestId)
180
181
  })
181
182
 
182
183
  // Listen for errors (prevents throwing)
@@ -218,6 +219,53 @@ Status is set to `succeeded` only after successful validation. If validation fai
218
219
 
219
220
  See [Event Examples](./examples/events/) for detailed usage patterns.
220
221
 
222
+ #### Accessing Request IDs
223
+
224
+ Every API request to Tela returns a unique `requestId` (from the `x-request-id` header) that can be used for debugging, tracking, and correlating with server logs. The SDK exposes request IDs in three ways:
225
+
226
+ ```typescript
227
+ const canvas = await tela.canvas.get({ id: 'canvas-id' })
228
+
229
+ // Start an async execution
230
+ const execution = await canvas.execute(
231
+ { query: 'test' },
232
+ { async: true }
233
+ )
234
+
235
+ // Method 1: Access directly from execution object
236
+ // This is the request ID from the initial request that created the execution
237
+ const requestId = await execution.requestId
238
+ console.log('Request ID:', requestId)
239
+
240
+ // Method 2: Access from poll events
241
+ // Each poll event includes the request ID from that specific polling request
242
+ execution.on('poll', (pollResult) => {
243
+ console.log('Request ID from this poll:', pollResult.requestId)
244
+ })
245
+
246
+ // Method 3: Access from success event
247
+ // The success event includes the request ID from the final successful polling request
248
+ execution.on('success', (result) => {
249
+ console.log('Request ID from final request:', result.requestId)
250
+ })
251
+
252
+ // Start polling
253
+ execution.poll()
254
+ ```
255
+
256
+ **Important Notes:**
257
+ - `execution.requestId` - Request ID from the execution creation request (POST /v2/chat/completions)
258
+ - `pollResult.requestId` - Request ID from each individual polling request (GET /v2/chat/completions/:id)
259
+ - `result.requestId` - Request ID from the final successful polling request
260
+
261
+ **Use Cases:**
262
+ - **Debugging**: Identify specific API requests when troubleshooting issues
263
+ - **Logging**: Track individual requests across distributed systems
264
+ - **Support**: Reference specific requests in support tickets
265
+ - **Monitoring**: Correlate client requests with server logs and traces
266
+
267
+ See [Request ID Example](./examples/events/request-id.ts) for a complete demonstration.
268
+
221
269
  #### Schema Validation
222
270
 
223
271
  The Canvas API validates your inputs and outputs against the server schema:
package/dist/index.cjs CHANGED
@@ -24,7 +24,7 @@ const z__default = /*#__PURE__*/_interopDefaultCompat(z);
24
24
  const z__namespace = /*#__PURE__*/_interopNamespaceCompat(z);
25
25
  const Emittery__default = /*#__PURE__*/_interopDefaultCompat(Emittery);
26
26
 
27
- const version = "2.3.0";
27
+ const version = "2.3.2";
28
28
 
29
29
  var __defProp$7 = Object.defineProperty;
30
30
  var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -319,13 +319,10 @@ class Stream {
319
319
  * @param iterator - A function that returns an AsyncIterator<Item>.
320
320
  * @param controller - The AbortController for this stream.
321
321
  */
322
- constructor(iterator, controller) {
322
+ constructor(iterator, controller, requestId) {
323
323
  this.iterator = iterator;
324
- /**
325
- * The AbortController associated with this stream.
326
- */
327
- __publicField$6(this, "controller");
328
324
  this.controller = controller;
325
+ this.requestId = requestId;
329
326
  }
330
327
  /**
331
328
  * Creates a Stream from a server-sent events (SSE) Response.
@@ -399,7 +396,8 @@ class Stream {
399
396
  controller.abort();
400
397
  }
401
398
  }
402
- return new Stream(iterator, controller);
399
+ const requestId = response.headers.get("x-request-id") || response.headers.get("request-id") || "";
400
+ return new Stream(iterator, controller, requestId);
403
401
  }
404
402
  /**
405
403
  * Creates a Stream from a newline-separated ReadableStream where each item is a JSON value.
@@ -739,6 +737,43 @@ var __publicField$5 = (obj, key, value) => {
739
737
  __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
740
738
  return value;
741
739
  };
740
+ function getRequestIdFromResponse(response) {
741
+ try {
742
+ if (typeof response.headers.get === "function") {
743
+ return response.headers.get("x-request-id") || void 0;
744
+ }
745
+ if (typeof response.headers.toJSON === "function") {
746
+ const headers = response.headers.toJSON();
747
+ return headers["x-request-id"] || void 0;
748
+ }
749
+ if ("entries" in response.headers && typeof response.headers.entries === "function") {
750
+ for (const [key, value] of response.headers.entries()) {
751
+ if (key.toLowerCase() === "x-request-id") {
752
+ return value;
753
+ }
754
+ }
755
+ }
756
+ if (typeof response.headers.forEach === "function") {
757
+ let requestId;
758
+ response.headers.forEach((value, key) => {
759
+ if (key.toLowerCase() === "x-request-id") {
760
+ requestId = value;
761
+ }
762
+ });
763
+ return requestId;
764
+ }
765
+ if (response.headers && typeof response.headers[Symbol.iterator] === "function") {
766
+ for (const [key, value] of response.headers) {
767
+ if (key.toLowerCase() === "x-request-id") {
768
+ return value;
769
+ }
770
+ }
771
+ }
772
+ return void 0;
773
+ } catch {
774
+ return void 0;
775
+ }
776
+ }
742
777
  async function defaultParseResponse(props) {
743
778
  const { response } = props;
744
779
  if (props.options.stream) {
@@ -753,7 +788,12 @@ async function defaultParseResponse(props) {
753
788
  if (isJSON) {
754
789
  const json = await response.json();
755
790
  debug("response", response.status, response.url, response.headers, json);
756
- return transformObjectFromSnakeCaseToCamelCase({ ...json, headers: response.headers.toJSON() }, DEFAULT_FIELDS_TRANSFORMATION_EXCLUSIONS);
791
+ const requestId = getRequestIdFromResponse(response);
792
+ const finalJson = { ...json };
793
+ if (requestId) {
794
+ finalJson.requestId = requestId;
795
+ }
796
+ return transformObjectFromSnakeCaseToCamelCase(finalJson, DEFAULT_FIELDS_TRANSFORMATION_EXCLUSIONS);
757
797
  }
758
798
  const text = await response.text();
759
799
  debug("response", response.status, response.url, response.headers, text);
@@ -1540,6 +1580,7 @@ class CanvasExecution extends Emittery__default {
1540
1580
  __publicField$2(this, "_resultPromise");
1541
1581
  __publicField$2(this, "_stream");
1542
1582
  __publicField$2(this, "_rawResultValue");
1583
+ __publicField$2(this, "_requestId");
1543
1584
  this._variables = variables;
1544
1585
  this._params = params;
1545
1586
  this._outputSchema = outputSchema;
@@ -1635,6 +1676,53 @@ class CanvasExecution extends Emittery__default {
1635
1676
  }
1636
1677
  return this._id;
1637
1678
  }
1679
+ /**
1680
+ * Gets the request ID from the `x-request-id` header of the execution creation request.
1681
+ *
1682
+ * This is the request ID from the initial POST /v2/chat/completions request that created
1683
+ * the execution. Each API request has its own unique request ID.
1684
+ *
1685
+ * For async executions, different request IDs are available:
1686
+ * - `execution.requestId` - ID from the execution creation request
1687
+ * - `pollResult.requestId` - ID from each polling request (in poll events)
1688
+ * - `result.requestId` - ID from the final successful polling request (in success events)
1689
+ *
1690
+ * @throws {ExecutionNotStartedError} If the execution has not been started yet.
1691
+ * @returns A promise that resolves to the request ID from the execution creation request.
1692
+ *
1693
+ * @example
1694
+ * ```typescript
1695
+ * const execution = await canvas.execute({ query: 'test' })
1696
+ * const requestId = await execution.requestId
1697
+ * console.log('Request ID:', requestId)
1698
+ * ```
1699
+ *
1700
+ * @example Accessing different request IDs in async executions
1701
+ * ```typescript
1702
+ * const execution = await canvas.execute({ query: 'test' }, { async: true })
1703
+ *
1704
+ * // Request ID from execution creation
1705
+ * const creationRequestId = await execution.requestId
1706
+ *
1707
+ * // Request IDs from polling
1708
+ * execution.on('poll', (pollResult) => {
1709
+ * console.log('Poll request ID:', pollResult.requestId)
1710
+ * })
1711
+ *
1712
+ * // Request ID from final result
1713
+ * execution.on('success', (result) => {
1714
+ * console.log('Final request ID:', result.requestId)
1715
+ * })
1716
+ *
1717
+ * execution.poll()
1718
+ * ```
1719
+ */
1720
+ get requestId() {
1721
+ if (!this._requestId) {
1722
+ throw new ExecutionNotStartedError();
1723
+ }
1724
+ return this._requestId;
1725
+ }
1638
1726
  /**
1639
1727
  * Gets the latest known status of the execution.
1640
1728
  *
@@ -1919,31 +2007,48 @@ class CanvasExecution extends Emittery__default {
1919
2007
  return variables;
1920
2008
  }
1921
2009
  /**
1922
- * Initiates a synchronous execution that waits for the complete result.
1923
- * The result is validated against the output schema if provided.
1924
- *
1925
- * @returns A promise resolving to the parsed execution result.
2010
+ * Creates an execution on the server by making a POST request to /v2/chat/completions.
2011
+ * This method is shared between sync, async, and streaming execution modes.
2012
+ * Automatically sets the _requestId property from response headers.
2013
+ *
2014
+ * @template TResponse - The expected response type (sync, async, or stream).
2015
+ * @param resolvedVariables - The processed variables with uploaded files.
2016
+ * @param options - Execution options.
2017
+ * @param options.async - Whether to create an async execution.
2018
+ * @param options.stream - Whether to create a streaming execution.
2019
+ * @returns A promise resolving to the execution creation response or stream.
1926
2020
  */
1927
- async startSync() {
1928
- const resolvedVariables = await this.resolveVariables();
2021
+ async create(resolvedVariables, options = {}) {
1929
2022
  const body = {
1930
- async: this._params.async ?? false,
1931
- stream: false,
2023
+ async: options.async ?? false,
2024
+ stream: options.stream ?? false,
1932
2025
  ...this.baseBody,
1933
2026
  variables: resolvedVariables
1934
2027
  };
1935
- this._resultPromise = this._client.post("/v2/chat/completions", {
2028
+ const responsePromise = this._client.post("/v2/chat/completions", {
1936
2029
  body,
1937
- stream: false,
2030
+ stream: options.stream ?? false,
1938
2031
  signal: this._abortController.signal
1939
- }).then((response) => {
2032
+ });
2033
+ this._requestId = responsePromise.then((response) => response?.requestId || "").catch(() => "");
2034
+ return await responsePromise;
2035
+ }
2036
+ /**
2037
+ * Initiates a synchronous execution that waits for the complete result.
2038
+ * The result is validated against the output schema if provided.
2039
+ *
2040
+ * @returns A promise resolving to the parsed execution result.
2041
+ */
2042
+ async startSync() {
2043
+ const resolvedVariables = await this.resolveVariables();
2044
+ this._resultPromise = this.create(resolvedVariables, { async: false }).then((response) => {
1940
2045
  this._id = response.id;
1941
2046
  this._rawResultValue = response;
1942
2047
  return { content: getResultFromPollingResponse(response), response };
1943
2048
  }).then(({ content, response }) => {
1944
2049
  const validatedContent = this._skipResultValidation || !(this._outputSchema instanceof z__default.ZodType) ? content : this._outputSchema.parse(content);
1945
2050
  this.status = "succeeded";
1946
- this.emit("success", { ...validatedContent, headers: response?.headers ?? {} });
2051
+ this.emit("success", { ...validatedContent, requestId: response?.requestId });
1947
2052
  return validatedContent;
1948
2053
  }).catch((error) => {
1949
2054
  this.status = "failed";
@@ -1963,17 +2068,7 @@ class CanvasExecution extends Emittery__default {
1963
2068
  */
1964
2069
  async startAsync() {
1965
2070
  const resolvedVariables = await this.resolveVariables();
1966
- const body = {
1967
- async: true,
1968
- stream: false,
1969
- ...this.baseBody,
1970
- variables: resolvedVariables
1971
- };
1972
- return await this._client.post("/v2/chat/completions", {
1973
- body,
1974
- stream: false,
1975
- signal: this._abortController.signal
1976
- }).then((response) => {
2071
+ return await this.create(resolvedVariables, { async: true }).then((response) => {
1977
2072
  this._id = response.id;
1978
2073
  this.status = response.status;
1979
2074
  this.emit("poll", {
@@ -1981,7 +2076,7 @@ class CanvasExecution extends Emittery__default {
1981
2076
  status: response.status,
1982
2077
  outputContent: response.output_content,
1983
2078
  rawOutput: response.raw_output,
1984
- headers: response.headers
2079
+ requestId: response.requestId
1985
2080
  });
1986
2081
  return response;
1987
2082
  });
@@ -1993,16 +2088,7 @@ class CanvasExecution extends Emittery__default {
1993
2088
  */
1994
2089
  async startStream() {
1995
2090
  const resolvedVariables = await this.resolveVariables();
1996
- const body = {
1997
- ...this.baseBody,
1998
- stream: true,
1999
- variables: resolvedVariables
2000
- };
2001
- this._stream = await this._client.post("/v2/chat/completions", {
2002
- body,
2003
- stream: true,
2004
- signal: this._abortController.signal
2005
- });
2091
+ this._stream = await this.create(resolvedVariables, { stream: true });
2006
2092
  this.status = "streaming";
2007
2093
  return this._stream;
2008
2094
  }
@@ -2046,7 +2132,7 @@ class CanvasExecution extends Emittery__default {
2046
2132
  };
2047
2133
  }
2048
2134
  this._rawResultValue = response;
2049
- this.emit("success", { ...getResultFromPollingResponse(response), headers: response?.headers ?? {} });
2135
+ this.emit("success", { ...getResultFromPollingResponse(response), requestId: response?.requestId });
2050
2136
  return {
2051
2137
  done: response.status === "succeeded",
2052
2138
  value: getResultFromPollingResponse(response)
package/dist/index.d.cts CHANGED
@@ -620,6 +620,17 @@ type AsyncCompletionCreateResult = {
620
620
  * This type will be refined in future versions with proper typing.
621
621
  */
622
622
  type RawAPIResult = any;
623
+ /**
624
+ * Helper type to add request ID to a response type.
625
+ *
626
+ * The `requestId` field contains the value from the `x-request-id` HTTP header
627
+ * returned by the API for that specific request.
628
+ *
629
+ * @template T - The base response type.
630
+ */
631
+ type WithRequestId<T> = T & {
632
+ requestId?: string;
633
+ };
623
634
  /**
624
635
  * Result returned when polling for asynchronous execution status.
625
636
  *
@@ -662,13 +673,21 @@ type ExecutionParams = AsyncExecutionParams | StreamExecutionParams | SyncExecut
662
673
  * @returns AsyncGenerator for streaming executions, Promise otherwise.
663
674
  */
664
675
  type CanvasExecutionResult<TParams, TOutput = unknown> = TParams extends StreamExecutionParams ? AsyncGenerator<Partial<TOutput>> : Promise<TOutput>;
676
+ /**
677
+ * Event types emitted by CanvasExecution during its lifecycle.
678
+ *
679
+ * @template TOutput - The output type.
680
+ *
681
+ * @property poll - Emitted during async polling with current status and output. Includes `requestId` from the polling request.
682
+ * @property success - Emitted when execution completes successfully with the final result. Includes `requestId` from the final request.
683
+ * @property error - Emitted when execution fails with the error object.
684
+ * @property statusChange - Emitted when execution status transitions to a new state.
685
+ *
686
+ * @category Canvas
687
+ */
665
688
  type CanvasExecutionEvents<TOutput> = {
666
- poll: AsyncCompletionPollingResult<TOutput> & {
667
- headers: Record<string, string>;
668
- };
669
- success: TOutput & {
670
- headers: Record<string, string>;
671
- };
689
+ poll: WithRequestId<AsyncCompletionPollingResult<TOutput>>;
690
+ success: WithRequestId<TOutput>;
672
691
  error: ExecutionFailedError;
673
692
  statusChange: ExecutionStatus;
674
693
  };
@@ -701,8 +720,8 @@ type CanvasExecutionEvents<TOutput> = {
701
720
  * @typeParam TInput - The input variables type
702
721
  * @typeParam TOutput - The output result type
703
722
  *
704
- * @fires poll - Emitted during async polling with current status and output (async executions only)
705
- * @fires success - Emitted when execution completes successfully with the final result
723
+ * @fires poll - Emitted during async polling with current status and output. Includes `requestId` from the polling request. (async executions only)
724
+ * @fires success - Emitted when execution completes successfully with the final result. Includes `requestId` from the final request.
706
725
  * @fires error - Emitted when execution fails (only if error listeners are registered, otherwise throws)
707
726
  * @fires statusChange - Emitted when execution status transitions to a new state
708
727
  *
@@ -734,6 +753,7 @@ declare class CanvasExecution<TParams extends ExecutionParams = SyncExecutionPar
734
753
  private _resultPromise;
735
754
  private _stream;
736
755
  private _rawResultValue;
756
+ private _requestId;
737
757
  /**
738
758
  * Creates a new canvas execution instance.
739
759
  *
@@ -784,6 +804,48 @@ declare class CanvasExecution<TParams extends ExecutionParams = SyncExecutionPar
784
804
  * @returns The execution ID.
785
805
  */
786
806
  get id(): string;
807
+ /**
808
+ * Gets the request ID from the `x-request-id` header of the execution creation request.
809
+ *
810
+ * This is the request ID from the initial POST /v2/chat/completions request that created
811
+ * the execution. Each API request has its own unique request ID.
812
+ *
813
+ * For async executions, different request IDs are available:
814
+ * - `execution.requestId` - ID from the execution creation request
815
+ * - `pollResult.requestId` - ID from each polling request (in poll events)
816
+ * - `result.requestId` - ID from the final successful polling request (in success events)
817
+ *
818
+ * @throws {ExecutionNotStartedError} If the execution has not been started yet.
819
+ * @returns A promise that resolves to the request ID from the execution creation request.
820
+ *
821
+ * @example
822
+ * ```typescript
823
+ * const execution = await canvas.execute({ query: 'test' })
824
+ * const requestId = await execution.requestId
825
+ * console.log('Request ID:', requestId)
826
+ * ```
827
+ *
828
+ * @example Accessing different request IDs in async executions
829
+ * ```typescript
830
+ * const execution = await canvas.execute({ query: 'test' }, { async: true })
831
+ *
832
+ * // Request ID from execution creation
833
+ * const creationRequestId = await execution.requestId
834
+ *
835
+ * // Request IDs from polling
836
+ * execution.on('poll', (pollResult) => {
837
+ * console.log('Poll request ID:', pollResult.requestId)
838
+ * })
839
+ *
840
+ * // Request ID from final result
841
+ * execution.on('success', (result) => {
842
+ * console.log('Final request ID:', result.requestId)
843
+ * })
844
+ *
845
+ * execution.poll()
846
+ * ```
847
+ */
848
+ get requestId(): Promise<string>;
787
849
  /**
788
850
  * Gets the latest known status of the execution.
789
851
  *
@@ -871,9 +933,7 @@ declare class CanvasExecution<TParams extends ExecutionParams = SyncExecutionPar
871
933
  *
872
934
  * @returns A promise or async generator depending on execution mode.
873
935
  */
874
- start(): Promise<CanvasExecutionResult<TParams, TOutput>> | AsyncGenerator<Partial<TOutput>, any, any> | Promise<AsyncGenerator<Partial<TOutput>, any, any>> | Promise<AsyncCompletionCreateResult & {
875
- headers: Record<string, string>;
876
- }>;
936
+ start(): Promise<CanvasExecutionResult<TParams, TOutput>> | AsyncGenerator<Partial<TOutput>, any, any> | Promise<AsyncGenerator<Partial<TOutput>, any, any>> | Promise<WithRequestId<AsyncCompletionCreateResult>>;
877
937
  /**
878
938
  * Gets the execution result. For async executions, automatically starts polling.
879
939
  * For sync executions, returns the result promise. For streams, returns the generator.
@@ -949,6 +1009,19 @@ declare class CanvasExecution<TParams extends ExecutionParams = SyncExecutionPar
949
1009
  * @returns A promise resolving to the processed variables object.
950
1010
  */
951
1011
  private resolveVariables;
1012
+ /**
1013
+ * Creates an execution on the server by making a POST request to /v2/chat/completions.
1014
+ * This method is shared between sync, async, and streaming execution modes.
1015
+ * Automatically sets the _requestId property from response headers.
1016
+ *
1017
+ * @template TResponse - The expected response type (sync, async, or stream).
1018
+ * @param resolvedVariables - The processed variables with uploaded files.
1019
+ * @param options - Execution options.
1020
+ * @param options.async - Whether to create an async execution.
1021
+ * @param options.stream - Whether to create a streaming execution.
1022
+ * @returns A promise resolving to the execution creation response or stream.
1023
+ */
1024
+ private create;
952
1025
  /**
953
1026
  * Initiates a synchronous execution that waits for the complete result.
954
1027
  * The result is validated against the output schema if provided.
package/dist/index.d.mts CHANGED
@@ -620,6 +620,17 @@ type AsyncCompletionCreateResult = {
620
620
  * This type will be refined in future versions with proper typing.
621
621
  */
622
622
  type RawAPIResult = any;
623
+ /**
624
+ * Helper type to add request ID to a response type.
625
+ *
626
+ * The `requestId` field contains the value from the `x-request-id` HTTP header
627
+ * returned by the API for that specific request.
628
+ *
629
+ * @template T - The base response type.
630
+ */
631
+ type WithRequestId<T> = T & {
632
+ requestId?: string;
633
+ };
623
634
  /**
624
635
  * Result returned when polling for asynchronous execution status.
625
636
  *
@@ -662,13 +673,21 @@ type ExecutionParams = AsyncExecutionParams | StreamExecutionParams | SyncExecut
662
673
  * @returns AsyncGenerator for streaming executions, Promise otherwise.
663
674
  */
664
675
  type CanvasExecutionResult<TParams, TOutput = unknown> = TParams extends StreamExecutionParams ? AsyncGenerator<Partial<TOutput>> : Promise<TOutput>;
676
+ /**
677
+ * Event types emitted by CanvasExecution during its lifecycle.
678
+ *
679
+ * @template TOutput - The output type.
680
+ *
681
+ * @property poll - Emitted during async polling with current status and output. Includes `requestId` from the polling request.
682
+ * @property success - Emitted when execution completes successfully with the final result. Includes `requestId` from the final request.
683
+ * @property error - Emitted when execution fails with the error object.
684
+ * @property statusChange - Emitted when execution status transitions to a new state.
685
+ *
686
+ * @category Canvas
687
+ */
665
688
  type CanvasExecutionEvents<TOutput> = {
666
- poll: AsyncCompletionPollingResult<TOutput> & {
667
- headers: Record<string, string>;
668
- };
669
- success: TOutput & {
670
- headers: Record<string, string>;
671
- };
689
+ poll: WithRequestId<AsyncCompletionPollingResult<TOutput>>;
690
+ success: WithRequestId<TOutput>;
672
691
  error: ExecutionFailedError;
673
692
  statusChange: ExecutionStatus;
674
693
  };
@@ -701,8 +720,8 @@ type CanvasExecutionEvents<TOutput> = {
701
720
  * @typeParam TInput - The input variables type
702
721
  * @typeParam TOutput - The output result type
703
722
  *
704
- * @fires poll - Emitted during async polling with current status and output (async executions only)
705
- * @fires success - Emitted when execution completes successfully with the final result
723
+ * @fires poll - Emitted during async polling with current status and output. Includes `requestId` from the polling request. (async executions only)
724
+ * @fires success - Emitted when execution completes successfully with the final result. Includes `requestId` from the final request.
706
725
  * @fires error - Emitted when execution fails (only if error listeners are registered, otherwise throws)
707
726
  * @fires statusChange - Emitted when execution status transitions to a new state
708
727
  *
@@ -734,6 +753,7 @@ declare class CanvasExecution<TParams extends ExecutionParams = SyncExecutionPar
734
753
  private _resultPromise;
735
754
  private _stream;
736
755
  private _rawResultValue;
756
+ private _requestId;
737
757
  /**
738
758
  * Creates a new canvas execution instance.
739
759
  *
@@ -784,6 +804,48 @@ declare class CanvasExecution<TParams extends ExecutionParams = SyncExecutionPar
784
804
  * @returns The execution ID.
785
805
  */
786
806
  get id(): string;
807
+ /**
808
+ * Gets the request ID from the `x-request-id` header of the execution creation request.
809
+ *
810
+ * This is the request ID from the initial POST /v2/chat/completions request that created
811
+ * the execution. Each API request has its own unique request ID.
812
+ *
813
+ * For async executions, different request IDs are available:
814
+ * - `execution.requestId` - ID from the execution creation request
815
+ * - `pollResult.requestId` - ID from each polling request (in poll events)
816
+ * - `result.requestId` - ID from the final successful polling request (in success events)
817
+ *
818
+ * @throws {ExecutionNotStartedError} If the execution has not been started yet.
819
+ * @returns A promise that resolves to the request ID from the execution creation request.
820
+ *
821
+ * @example
822
+ * ```typescript
823
+ * const execution = await canvas.execute({ query: 'test' })
824
+ * const requestId = await execution.requestId
825
+ * console.log('Request ID:', requestId)
826
+ * ```
827
+ *
828
+ * @example Accessing different request IDs in async executions
829
+ * ```typescript
830
+ * const execution = await canvas.execute({ query: 'test' }, { async: true })
831
+ *
832
+ * // Request ID from execution creation
833
+ * const creationRequestId = await execution.requestId
834
+ *
835
+ * // Request IDs from polling
836
+ * execution.on('poll', (pollResult) => {
837
+ * console.log('Poll request ID:', pollResult.requestId)
838
+ * })
839
+ *
840
+ * // Request ID from final result
841
+ * execution.on('success', (result) => {
842
+ * console.log('Final request ID:', result.requestId)
843
+ * })
844
+ *
845
+ * execution.poll()
846
+ * ```
847
+ */
848
+ get requestId(): Promise<string>;
787
849
  /**
788
850
  * Gets the latest known status of the execution.
789
851
  *
@@ -871,9 +933,7 @@ declare class CanvasExecution<TParams extends ExecutionParams = SyncExecutionPar
871
933
  *
872
934
  * @returns A promise or async generator depending on execution mode.
873
935
  */
874
- start(): Promise<CanvasExecutionResult<TParams, TOutput>> | AsyncGenerator<Partial<TOutput>, any, any> | Promise<AsyncGenerator<Partial<TOutput>, any, any>> | Promise<AsyncCompletionCreateResult & {
875
- headers: Record<string, string>;
876
- }>;
936
+ start(): Promise<CanvasExecutionResult<TParams, TOutput>> | AsyncGenerator<Partial<TOutput>, any, any> | Promise<AsyncGenerator<Partial<TOutput>, any, any>> | Promise<WithRequestId<AsyncCompletionCreateResult>>;
877
937
  /**
878
938
  * Gets the execution result. For async executions, automatically starts polling.
879
939
  * For sync executions, returns the result promise. For streams, returns the generator.
@@ -949,6 +1009,19 @@ declare class CanvasExecution<TParams extends ExecutionParams = SyncExecutionPar
949
1009
  * @returns A promise resolving to the processed variables object.
950
1010
  */
951
1011
  private resolveVariables;
1012
+ /**
1013
+ * Creates an execution on the server by making a POST request to /v2/chat/completions.
1014
+ * This method is shared between sync, async, and streaming execution modes.
1015
+ * Automatically sets the _requestId property from response headers.
1016
+ *
1017
+ * @template TResponse - The expected response type (sync, async, or stream).
1018
+ * @param resolvedVariables - The processed variables with uploaded files.
1019
+ * @param options - Execution options.
1020
+ * @param options.async - Whether to create an async execution.
1021
+ * @param options.stream - Whether to create a streaming execution.
1022
+ * @returns A promise resolving to the execution creation response or stream.
1023
+ */
1024
+ private create;
952
1025
  /**
953
1026
  * Initiates a synchronous execution that waits for the complete result.
954
1027
  * The result is validated against the output schema if provided.
package/dist/index.d.ts CHANGED
@@ -620,6 +620,17 @@ type AsyncCompletionCreateResult = {
620
620
  * This type will be refined in future versions with proper typing.
621
621
  */
622
622
  type RawAPIResult = any;
623
+ /**
624
+ * Helper type to add request ID to a response type.
625
+ *
626
+ * The `requestId` field contains the value from the `x-request-id` HTTP header
627
+ * returned by the API for that specific request.
628
+ *
629
+ * @template T - The base response type.
630
+ */
631
+ type WithRequestId<T> = T & {
632
+ requestId?: string;
633
+ };
623
634
  /**
624
635
  * Result returned when polling for asynchronous execution status.
625
636
  *
@@ -662,13 +673,21 @@ type ExecutionParams = AsyncExecutionParams | StreamExecutionParams | SyncExecut
662
673
  * @returns AsyncGenerator for streaming executions, Promise otherwise.
663
674
  */
664
675
  type CanvasExecutionResult<TParams, TOutput = unknown> = TParams extends StreamExecutionParams ? AsyncGenerator<Partial<TOutput>> : Promise<TOutput>;
676
+ /**
677
+ * Event types emitted by CanvasExecution during its lifecycle.
678
+ *
679
+ * @template TOutput - The output type.
680
+ *
681
+ * @property poll - Emitted during async polling with current status and output. Includes `requestId` from the polling request.
682
+ * @property success - Emitted when execution completes successfully with the final result. Includes `requestId` from the final request.
683
+ * @property error - Emitted when execution fails with the error object.
684
+ * @property statusChange - Emitted when execution status transitions to a new state.
685
+ *
686
+ * @category Canvas
687
+ */
665
688
  type CanvasExecutionEvents<TOutput> = {
666
- poll: AsyncCompletionPollingResult<TOutput> & {
667
- headers: Record<string, string>;
668
- };
669
- success: TOutput & {
670
- headers: Record<string, string>;
671
- };
689
+ poll: WithRequestId<AsyncCompletionPollingResult<TOutput>>;
690
+ success: WithRequestId<TOutput>;
672
691
  error: ExecutionFailedError;
673
692
  statusChange: ExecutionStatus;
674
693
  };
@@ -701,8 +720,8 @@ type CanvasExecutionEvents<TOutput> = {
701
720
  * @typeParam TInput - The input variables type
702
721
  * @typeParam TOutput - The output result type
703
722
  *
704
- * @fires poll - Emitted during async polling with current status and output (async executions only)
705
- * @fires success - Emitted when execution completes successfully with the final result
723
+ * @fires poll - Emitted during async polling with current status and output. Includes `requestId` from the polling request. (async executions only)
724
+ * @fires success - Emitted when execution completes successfully with the final result. Includes `requestId` from the final request.
706
725
  * @fires error - Emitted when execution fails (only if error listeners are registered, otherwise throws)
707
726
  * @fires statusChange - Emitted when execution status transitions to a new state
708
727
  *
@@ -734,6 +753,7 @@ declare class CanvasExecution<TParams extends ExecutionParams = SyncExecutionPar
734
753
  private _resultPromise;
735
754
  private _stream;
736
755
  private _rawResultValue;
756
+ private _requestId;
737
757
  /**
738
758
  * Creates a new canvas execution instance.
739
759
  *
@@ -784,6 +804,48 @@ declare class CanvasExecution<TParams extends ExecutionParams = SyncExecutionPar
784
804
  * @returns The execution ID.
785
805
  */
786
806
  get id(): string;
807
+ /**
808
+ * Gets the request ID from the `x-request-id` header of the execution creation request.
809
+ *
810
+ * This is the request ID from the initial POST /v2/chat/completions request that created
811
+ * the execution. Each API request has its own unique request ID.
812
+ *
813
+ * For async executions, different request IDs are available:
814
+ * - `execution.requestId` - ID from the execution creation request
815
+ * - `pollResult.requestId` - ID from each polling request (in poll events)
816
+ * - `result.requestId` - ID from the final successful polling request (in success events)
817
+ *
818
+ * @throws {ExecutionNotStartedError} If the execution has not been started yet.
819
+ * @returns A promise that resolves to the request ID from the execution creation request.
820
+ *
821
+ * @example
822
+ * ```typescript
823
+ * const execution = await canvas.execute({ query: 'test' })
824
+ * const requestId = await execution.requestId
825
+ * console.log('Request ID:', requestId)
826
+ * ```
827
+ *
828
+ * @example Accessing different request IDs in async executions
829
+ * ```typescript
830
+ * const execution = await canvas.execute({ query: 'test' }, { async: true })
831
+ *
832
+ * // Request ID from execution creation
833
+ * const creationRequestId = await execution.requestId
834
+ *
835
+ * // Request IDs from polling
836
+ * execution.on('poll', (pollResult) => {
837
+ * console.log('Poll request ID:', pollResult.requestId)
838
+ * })
839
+ *
840
+ * // Request ID from final result
841
+ * execution.on('success', (result) => {
842
+ * console.log('Final request ID:', result.requestId)
843
+ * })
844
+ *
845
+ * execution.poll()
846
+ * ```
847
+ */
848
+ get requestId(): Promise<string>;
787
849
  /**
788
850
  * Gets the latest known status of the execution.
789
851
  *
@@ -871,9 +933,7 @@ declare class CanvasExecution<TParams extends ExecutionParams = SyncExecutionPar
871
933
  *
872
934
  * @returns A promise or async generator depending on execution mode.
873
935
  */
874
- start(): Promise<CanvasExecutionResult<TParams, TOutput>> | AsyncGenerator<Partial<TOutput>, any, any> | Promise<AsyncGenerator<Partial<TOutput>, any, any>> | Promise<AsyncCompletionCreateResult & {
875
- headers: Record<string, string>;
876
- }>;
936
+ start(): Promise<CanvasExecutionResult<TParams, TOutput>> | AsyncGenerator<Partial<TOutput>, any, any> | Promise<AsyncGenerator<Partial<TOutput>, any, any>> | Promise<WithRequestId<AsyncCompletionCreateResult>>;
877
937
  /**
878
938
  * Gets the execution result. For async executions, automatically starts polling.
879
939
  * For sync executions, returns the result promise. For streams, returns the generator.
@@ -949,6 +1009,19 @@ declare class CanvasExecution<TParams extends ExecutionParams = SyncExecutionPar
949
1009
  * @returns A promise resolving to the processed variables object.
950
1010
  */
951
1011
  private resolveVariables;
1012
+ /**
1013
+ * Creates an execution on the server by making a POST request to /v2/chat/completions.
1014
+ * This method is shared between sync, async, and streaming execution modes.
1015
+ * Automatically sets the _requestId property from response headers.
1016
+ *
1017
+ * @template TResponse - The expected response type (sync, async, or stream).
1018
+ * @param resolvedVariables - The processed variables with uploaded files.
1019
+ * @param options - Execution options.
1020
+ * @param options.async - Whether to create an async execution.
1021
+ * @param options.stream - Whether to create a streaming execution.
1022
+ * @returns A promise resolving to the execution creation response or stream.
1023
+ */
1024
+ private create;
952
1025
  /**
953
1026
  * Initiates a synchronous execution that waits for the complete result.
954
1027
  * The result is validated against the output schema if provided.
package/dist/index.mjs CHANGED
@@ -4,7 +4,7 @@ import * as z from 'zod';
4
4
  import z__default, { z as z$1, ZodError } from 'zod';
5
5
  import Emittery from 'emittery';
6
6
 
7
- const version = "2.3.0";
7
+ const version = "2.3.2";
8
8
 
9
9
  var __defProp$7 = Object.defineProperty;
10
10
  var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -299,13 +299,10 @@ class Stream {
299
299
  * @param iterator - A function that returns an AsyncIterator<Item>.
300
300
  * @param controller - The AbortController for this stream.
301
301
  */
302
- constructor(iterator, controller) {
302
+ constructor(iterator, controller, requestId) {
303
303
  this.iterator = iterator;
304
- /**
305
- * The AbortController associated with this stream.
306
- */
307
- __publicField$6(this, "controller");
308
304
  this.controller = controller;
305
+ this.requestId = requestId;
309
306
  }
310
307
  /**
311
308
  * Creates a Stream from a server-sent events (SSE) Response.
@@ -379,7 +376,8 @@ class Stream {
379
376
  controller.abort();
380
377
  }
381
378
  }
382
- return new Stream(iterator, controller);
379
+ const requestId = response.headers.get("x-request-id") || response.headers.get("request-id") || "";
380
+ return new Stream(iterator, controller, requestId);
383
381
  }
384
382
  /**
385
383
  * Creates a Stream from a newline-separated ReadableStream where each item is a JSON value.
@@ -719,6 +717,43 @@ var __publicField$5 = (obj, key, value) => {
719
717
  __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
720
718
  return value;
721
719
  };
720
+ function getRequestIdFromResponse(response) {
721
+ try {
722
+ if (typeof response.headers.get === "function") {
723
+ return response.headers.get("x-request-id") || void 0;
724
+ }
725
+ if (typeof response.headers.toJSON === "function") {
726
+ const headers = response.headers.toJSON();
727
+ return headers["x-request-id"] || void 0;
728
+ }
729
+ if ("entries" in response.headers && typeof response.headers.entries === "function") {
730
+ for (const [key, value] of response.headers.entries()) {
731
+ if (key.toLowerCase() === "x-request-id") {
732
+ return value;
733
+ }
734
+ }
735
+ }
736
+ if (typeof response.headers.forEach === "function") {
737
+ let requestId;
738
+ response.headers.forEach((value, key) => {
739
+ if (key.toLowerCase() === "x-request-id") {
740
+ requestId = value;
741
+ }
742
+ });
743
+ return requestId;
744
+ }
745
+ if (response.headers && typeof response.headers[Symbol.iterator] === "function") {
746
+ for (const [key, value] of response.headers) {
747
+ if (key.toLowerCase() === "x-request-id") {
748
+ return value;
749
+ }
750
+ }
751
+ }
752
+ return void 0;
753
+ } catch {
754
+ return void 0;
755
+ }
756
+ }
722
757
  async function defaultParseResponse(props) {
723
758
  const { response } = props;
724
759
  if (props.options.stream) {
@@ -733,7 +768,12 @@ async function defaultParseResponse(props) {
733
768
  if (isJSON) {
734
769
  const json = await response.json();
735
770
  debug("response", response.status, response.url, response.headers, json);
736
- return transformObjectFromSnakeCaseToCamelCase({ ...json, headers: response.headers.toJSON() }, DEFAULT_FIELDS_TRANSFORMATION_EXCLUSIONS);
771
+ const requestId = getRequestIdFromResponse(response);
772
+ const finalJson = { ...json };
773
+ if (requestId) {
774
+ finalJson.requestId = requestId;
775
+ }
776
+ return transformObjectFromSnakeCaseToCamelCase(finalJson, DEFAULT_FIELDS_TRANSFORMATION_EXCLUSIONS);
737
777
  }
738
778
  const text = await response.text();
739
779
  debug("response", response.status, response.url, response.headers, text);
@@ -1520,6 +1560,7 @@ class CanvasExecution extends Emittery {
1520
1560
  __publicField$2(this, "_resultPromise");
1521
1561
  __publicField$2(this, "_stream");
1522
1562
  __publicField$2(this, "_rawResultValue");
1563
+ __publicField$2(this, "_requestId");
1523
1564
  this._variables = variables;
1524
1565
  this._params = params;
1525
1566
  this._outputSchema = outputSchema;
@@ -1615,6 +1656,53 @@ class CanvasExecution extends Emittery {
1615
1656
  }
1616
1657
  return this._id;
1617
1658
  }
1659
+ /**
1660
+ * Gets the request ID from the `x-request-id` header of the execution creation request.
1661
+ *
1662
+ * This is the request ID from the initial POST /v2/chat/completions request that created
1663
+ * the execution. Each API request has its own unique request ID.
1664
+ *
1665
+ * For async executions, different request IDs are available:
1666
+ * - `execution.requestId` - ID from the execution creation request
1667
+ * - `pollResult.requestId` - ID from each polling request (in poll events)
1668
+ * - `result.requestId` - ID from the final successful polling request (in success events)
1669
+ *
1670
+ * @throws {ExecutionNotStartedError} If the execution has not been started yet.
1671
+ * @returns A promise that resolves to the request ID from the execution creation request.
1672
+ *
1673
+ * @example
1674
+ * ```typescript
1675
+ * const execution = await canvas.execute({ query: 'test' })
1676
+ * const requestId = await execution.requestId
1677
+ * console.log('Request ID:', requestId)
1678
+ * ```
1679
+ *
1680
+ * @example Accessing different request IDs in async executions
1681
+ * ```typescript
1682
+ * const execution = await canvas.execute({ query: 'test' }, { async: true })
1683
+ *
1684
+ * // Request ID from execution creation
1685
+ * const creationRequestId = await execution.requestId
1686
+ *
1687
+ * // Request IDs from polling
1688
+ * execution.on('poll', (pollResult) => {
1689
+ * console.log('Poll request ID:', pollResult.requestId)
1690
+ * })
1691
+ *
1692
+ * // Request ID from final result
1693
+ * execution.on('success', (result) => {
1694
+ * console.log('Final request ID:', result.requestId)
1695
+ * })
1696
+ *
1697
+ * execution.poll()
1698
+ * ```
1699
+ */
1700
+ get requestId() {
1701
+ if (!this._requestId) {
1702
+ throw new ExecutionNotStartedError();
1703
+ }
1704
+ return this._requestId;
1705
+ }
1618
1706
  /**
1619
1707
  * Gets the latest known status of the execution.
1620
1708
  *
@@ -1899,31 +1987,48 @@ class CanvasExecution extends Emittery {
1899
1987
  return variables;
1900
1988
  }
1901
1989
  /**
1902
- * Initiates a synchronous execution that waits for the complete result.
1903
- * The result is validated against the output schema if provided.
1904
- *
1905
- * @returns A promise resolving to the parsed execution result.
1990
+ * Creates an execution on the server by making a POST request to /v2/chat/completions.
1991
+ * This method is shared between sync, async, and streaming execution modes.
1992
+ * Automatically sets the _requestId property from response headers.
1993
+ *
1994
+ * @template TResponse - The expected response type (sync, async, or stream).
1995
+ * @param resolvedVariables - The processed variables with uploaded files.
1996
+ * @param options - Execution options.
1997
+ * @param options.async - Whether to create an async execution.
1998
+ * @param options.stream - Whether to create a streaming execution.
1999
+ * @returns A promise resolving to the execution creation response or stream.
1906
2000
  */
1907
- async startSync() {
1908
- const resolvedVariables = await this.resolveVariables();
2001
+ async create(resolvedVariables, options = {}) {
1909
2002
  const body = {
1910
- async: this._params.async ?? false,
1911
- stream: false,
2003
+ async: options.async ?? false,
2004
+ stream: options.stream ?? false,
1912
2005
  ...this.baseBody,
1913
2006
  variables: resolvedVariables
1914
2007
  };
1915
- this._resultPromise = this._client.post("/v2/chat/completions", {
2008
+ const responsePromise = this._client.post("/v2/chat/completions", {
1916
2009
  body,
1917
- stream: false,
2010
+ stream: options.stream ?? false,
1918
2011
  signal: this._abortController.signal
1919
- }).then((response) => {
2012
+ });
2013
+ this._requestId = responsePromise.then((response) => response?.requestId || "").catch(() => "");
2014
+ return await responsePromise;
2015
+ }
2016
+ /**
2017
+ * Initiates a synchronous execution that waits for the complete result.
2018
+ * The result is validated against the output schema if provided.
2019
+ *
2020
+ * @returns A promise resolving to the parsed execution result.
2021
+ */
2022
+ async startSync() {
2023
+ const resolvedVariables = await this.resolveVariables();
2024
+ this._resultPromise = this.create(resolvedVariables, { async: false }).then((response) => {
1920
2025
  this._id = response.id;
1921
2026
  this._rawResultValue = response;
1922
2027
  return { content: getResultFromPollingResponse(response), response };
1923
2028
  }).then(({ content, response }) => {
1924
2029
  const validatedContent = this._skipResultValidation || !(this._outputSchema instanceof z__default.ZodType) ? content : this._outputSchema.parse(content);
1925
2030
  this.status = "succeeded";
1926
- this.emit("success", { ...validatedContent, headers: response?.headers ?? {} });
2031
+ this.emit("success", { ...validatedContent, requestId: response?.requestId });
1927
2032
  return validatedContent;
1928
2033
  }).catch((error) => {
1929
2034
  this.status = "failed";
@@ -1943,17 +2048,7 @@ class CanvasExecution extends Emittery {
1943
2048
  */
1944
2049
  async startAsync() {
1945
2050
  const resolvedVariables = await this.resolveVariables();
1946
- const body = {
1947
- async: true,
1948
- stream: false,
1949
- ...this.baseBody,
1950
- variables: resolvedVariables
1951
- };
1952
- return await this._client.post("/v2/chat/completions", {
1953
- body,
1954
- stream: false,
1955
- signal: this._abortController.signal
1956
- }).then((response) => {
2051
+ return await this.create(resolvedVariables, { async: true }).then((response) => {
1957
2052
  this._id = response.id;
1958
2053
  this.status = response.status;
1959
2054
  this.emit("poll", {
@@ -1961,7 +2056,7 @@ class CanvasExecution extends Emittery {
1961
2056
  status: response.status,
1962
2057
  outputContent: response.output_content,
1963
2058
  rawOutput: response.raw_output,
1964
- headers: response.headers
2059
+ requestId: response.requestId
1965
2060
  });
1966
2061
  return response;
1967
2062
  });
@@ -1973,16 +2068,7 @@ class CanvasExecution extends Emittery {
1973
2068
  */
1974
2069
  async startStream() {
1975
2070
  const resolvedVariables = await this.resolveVariables();
1976
- const body = {
1977
- ...this.baseBody,
1978
- stream: true,
1979
- variables: resolvedVariables
1980
- };
1981
- this._stream = await this._client.post("/v2/chat/completions", {
1982
- body,
1983
- stream: true,
1984
- signal: this._abortController.signal
1985
- });
2071
+ this._stream = await this.create(resolvedVariables, { stream: true });
1986
2072
  this.status = "streaming";
1987
2073
  return this._stream;
1988
2074
  }
@@ -2026,7 +2112,7 @@ class CanvasExecution extends Emittery {
2026
2112
  };
2027
2113
  }
2028
2114
  this._rawResultValue = response;
2029
- this.emit("success", { ...getResultFromPollingResponse(response), headers: response?.headers ?? {} });
2115
+ this.emit("success", { ...getResultFromPollingResponse(response), requestId: response?.requestId });
2030
2116
  return {
2031
2117
  done: response.status === "succeeded",
2032
2118
  value: getResultFromPollingResponse(response)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meistrari/tela-sdk-js",
3
- "version": "2.3.0",
3
+ "version": "2.3.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/meistrari/tela-sdk-js.git"