@meistrari/tela-sdk-js 2.3.1 → 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.1";
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,31 +737,41 @@ var __publicField$5 = (obj, key, value) => {
739
737
  __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
740
738
  return value;
741
739
  };
742
- function tryGetResponseHeaders(response) {
740
+ function getRequestIdFromResponse(response) {
743
741
  try {
742
+ if (typeof response.headers.get === "function") {
743
+ return response.headers.get("x-request-id") || void 0;
744
+ }
744
745
  if (typeof response.headers.toJSON === "function") {
745
- return response.headers.toJSON();
746
+ const headers = response.headers.toJSON();
747
+ return headers["x-request-id"] || void 0;
746
748
  }
747
749
  if ("entries" in response.headers && typeof response.headers.entries === "function") {
748
- return Object.fromEntries(response.headers.entries());
750
+ for (const [key, value] of response.headers.entries()) {
751
+ if (key.toLowerCase() === "x-request-id") {
752
+ return value;
753
+ }
754
+ }
749
755
  }
750
756
  if (typeof response.headers.forEach === "function") {
751
- const headers = {};
757
+ let requestId;
752
758
  response.headers.forEach((value, key) => {
753
- headers[key] = value;
759
+ if (key.toLowerCase() === "x-request-id") {
760
+ requestId = value;
761
+ }
754
762
  });
755
- return headers;
763
+ return requestId;
756
764
  }
757
765
  if (response.headers && typeof response.headers[Symbol.iterator] === "function") {
758
- const headers = {};
759
766
  for (const [key, value] of response.headers) {
760
- headers[key] = value;
767
+ if (key.toLowerCase() === "x-request-id") {
768
+ return value;
769
+ }
761
770
  }
762
- return headers;
763
771
  }
764
- return {};
772
+ return void 0;
765
773
  } catch {
766
- return {};
774
+ return void 0;
767
775
  }
768
776
  }
769
777
  async function defaultParseResponse(props) {
@@ -780,7 +788,12 @@ async function defaultParseResponse(props) {
780
788
  if (isJSON) {
781
789
  const json = await response.json();
782
790
  debug("response", response.status, response.url, response.headers, json);
783
- return transformObjectFromSnakeCaseToCamelCase({ ...json, headers: tryGetResponseHeaders(response) }, 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);
784
797
  }
785
798
  const text = await response.text();
786
799
  debug("response", response.status, response.url, response.headers, text);
@@ -1567,6 +1580,7 @@ class CanvasExecution extends Emittery__default {
1567
1580
  __publicField$2(this, "_resultPromise");
1568
1581
  __publicField$2(this, "_stream");
1569
1582
  __publicField$2(this, "_rawResultValue");
1583
+ __publicField$2(this, "_requestId");
1570
1584
  this._variables = variables;
1571
1585
  this._params = params;
1572
1586
  this._outputSchema = outputSchema;
@@ -1662,6 +1676,53 @@ class CanvasExecution extends Emittery__default {
1662
1676
  }
1663
1677
  return this._id;
1664
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
+ }
1665
1726
  /**
1666
1727
  * Gets the latest known status of the execution.
1667
1728
  *
@@ -1946,31 +2007,48 @@ class CanvasExecution extends Emittery__default {
1946
2007
  return variables;
1947
2008
  }
1948
2009
  /**
1949
- * Initiates a synchronous execution that waits for the complete result.
1950
- * The result is validated against the output schema if provided.
1951
- *
1952
- * @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.
1953
2020
  */
1954
- async startSync() {
1955
- const resolvedVariables = await this.resolveVariables();
2021
+ async create(resolvedVariables, options = {}) {
1956
2022
  const body = {
1957
- async: this._params.async ?? false,
1958
- stream: false,
2023
+ async: options.async ?? false,
2024
+ stream: options.stream ?? false,
1959
2025
  ...this.baseBody,
1960
2026
  variables: resolvedVariables
1961
2027
  };
1962
- this._resultPromise = this._client.post("/v2/chat/completions", {
2028
+ const responsePromise = this._client.post("/v2/chat/completions", {
1963
2029
  body,
1964
- stream: false,
2030
+ stream: options.stream ?? false,
1965
2031
  signal: this._abortController.signal
1966
- }).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) => {
1967
2045
  this._id = response.id;
1968
2046
  this._rawResultValue = response;
1969
2047
  return { content: getResultFromPollingResponse(response), response };
1970
2048
  }).then(({ content, response }) => {
1971
2049
  const validatedContent = this._skipResultValidation || !(this._outputSchema instanceof z__default.ZodType) ? content : this._outputSchema.parse(content);
1972
2050
  this.status = "succeeded";
1973
- this.emit("success", { ...validatedContent, headers: response?.headers ?? {} });
2051
+ this.emit("success", { ...validatedContent, requestId: response?.requestId });
1974
2052
  return validatedContent;
1975
2053
  }).catch((error) => {
1976
2054
  this.status = "failed";
@@ -1990,17 +2068,7 @@ class CanvasExecution extends Emittery__default {
1990
2068
  */
1991
2069
  async startAsync() {
1992
2070
  const resolvedVariables = await this.resolveVariables();
1993
- const body = {
1994
- async: true,
1995
- stream: false,
1996
- ...this.baseBody,
1997
- variables: resolvedVariables
1998
- };
1999
- return await this._client.post("/v2/chat/completions", {
2000
- body,
2001
- stream: false,
2002
- signal: this._abortController.signal
2003
- }).then((response) => {
2071
+ return await this.create(resolvedVariables, { async: true }).then((response) => {
2004
2072
  this._id = response.id;
2005
2073
  this.status = response.status;
2006
2074
  this.emit("poll", {
@@ -2008,7 +2076,7 @@ class CanvasExecution extends Emittery__default {
2008
2076
  status: response.status,
2009
2077
  outputContent: response.output_content,
2010
2078
  rawOutput: response.raw_output,
2011
- headers: response.headers
2079
+ requestId: response.requestId
2012
2080
  });
2013
2081
  return response;
2014
2082
  });
@@ -2020,16 +2088,7 @@ class CanvasExecution extends Emittery__default {
2020
2088
  */
2021
2089
  async startStream() {
2022
2090
  const resolvedVariables = await this.resolveVariables();
2023
- const body = {
2024
- ...this.baseBody,
2025
- stream: true,
2026
- variables: resolvedVariables
2027
- };
2028
- this._stream = await this._client.post("/v2/chat/completions", {
2029
- body,
2030
- stream: true,
2031
- signal: this._abortController.signal
2032
- });
2091
+ this._stream = await this.create(resolvedVariables, { stream: true });
2033
2092
  this.status = "streaming";
2034
2093
  return this._stream;
2035
2094
  }
@@ -2073,7 +2132,7 @@ class CanvasExecution extends Emittery__default {
2073
2132
  };
2074
2133
  }
2075
2134
  this._rawResultValue = response;
2076
- this.emit("success", { ...getResultFromPollingResponse(response), headers: response?.headers ?? {} });
2135
+ this.emit("success", { ...getResultFromPollingResponse(response), requestId: response?.requestId });
2077
2136
  return {
2078
2137
  done: response.status === "succeeded",
2079
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.1";
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,31 +717,41 @@ var __publicField$5 = (obj, key, value) => {
719
717
  __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
720
718
  return value;
721
719
  };
722
- function tryGetResponseHeaders(response) {
720
+ function getRequestIdFromResponse(response) {
723
721
  try {
722
+ if (typeof response.headers.get === "function") {
723
+ return response.headers.get("x-request-id") || void 0;
724
+ }
724
725
  if (typeof response.headers.toJSON === "function") {
725
- return response.headers.toJSON();
726
+ const headers = response.headers.toJSON();
727
+ return headers["x-request-id"] || void 0;
726
728
  }
727
729
  if ("entries" in response.headers && typeof response.headers.entries === "function") {
728
- return Object.fromEntries(response.headers.entries());
730
+ for (const [key, value] of response.headers.entries()) {
731
+ if (key.toLowerCase() === "x-request-id") {
732
+ return value;
733
+ }
734
+ }
729
735
  }
730
736
  if (typeof response.headers.forEach === "function") {
731
- const headers = {};
737
+ let requestId;
732
738
  response.headers.forEach((value, key) => {
733
- headers[key] = value;
739
+ if (key.toLowerCase() === "x-request-id") {
740
+ requestId = value;
741
+ }
734
742
  });
735
- return headers;
743
+ return requestId;
736
744
  }
737
745
  if (response.headers && typeof response.headers[Symbol.iterator] === "function") {
738
- const headers = {};
739
746
  for (const [key, value] of response.headers) {
740
- headers[key] = value;
747
+ if (key.toLowerCase() === "x-request-id") {
748
+ return value;
749
+ }
741
750
  }
742
- return headers;
743
751
  }
744
- return {};
752
+ return void 0;
745
753
  } catch {
746
- return {};
754
+ return void 0;
747
755
  }
748
756
  }
749
757
  async function defaultParseResponse(props) {
@@ -760,7 +768,12 @@ async function defaultParseResponse(props) {
760
768
  if (isJSON) {
761
769
  const json = await response.json();
762
770
  debug("response", response.status, response.url, response.headers, json);
763
- return transformObjectFromSnakeCaseToCamelCase({ ...json, headers: tryGetResponseHeaders(response) }, 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);
764
777
  }
765
778
  const text = await response.text();
766
779
  debug("response", response.status, response.url, response.headers, text);
@@ -1547,6 +1560,7 @@ class CanvasExecution extends Emittery {
1547
1560
  __publicField$2(this, "_resultPromise");
1548
1561
  __publicField$2(this, "_stream");
1549
1562
  __publicField$2(this, "_rawResultValue");
1563
+ __publicField$2(this, "_requestId");
1550
1564
  this._variables = variables;
1551
1565
  this._params = params;
1552
1566
  this._outputSchema = outputSchema;
@@ -1642,6 +1656,53 @@ class CanvasExecution extends Emittery {
1642
1656
  }
1643
1657
  return this._id;
1644
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
+ }
1645
1706
  /**
1646
1707
  * Gets the latest known status of the execution.
1647
1708
  *
@@ -1926,31 +1987,48 @@ class CanvasExecution extends Emittery {
1926
1987
  return variables;
1927
1988
  }
1928
1989
  /**
1929
- * Initiates a synchronous execution that waits for the complete result.
1930
- * The result is validated against the output schema if provided.
1931
- *
1932
- * @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.
1933
2000
  */
1934
- async startSync() {
1935
- const resolvedVariables = await this.resolveVariables();
2001
+ async create(resolvedVariables, options = {}) {
1936
2002
  const body = {
1937
- async: this._params.async ?? false,
1938
- stream: false,
2003
+ async: options.async ?? false,
2004
+ stream: options.stream ?? false,
1939
2005
  ...this.baseBody,
1940
2006
  variables: resolvedVariables
1941
2007
  };
1942
- this._resultPromise = this._client.post("/v2/chat/completions", {
2008
+ const responsePromise = this._client.post("/v2/chat/completions", {
1943
2009
  body,
1944
- stream: false,
2010
+ stream: options.stream ?? false,
1945
2011
  signal: this._abortController.signal
1946
- }).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) => {
1947
2025
  this._id = response.id;
1948
2026
  this._rawResultValue = response;
1949
2027
  return { content: getResultFromPollingResponse(response), response };
1950
2028
  }).then(({ content, response }) => {
1951
2029
  const validatedContent = this._skipResultValidation || !(this._outputSchema instanceof z__default.ZodType) ? content : this._outputSchema.parse(content);
1952
2030
  this.status = "succeeded";
1953
- this.emit("success", { ...validatedContent, headers: response?.headers ?? {} });
2031
+ this.emit("success", { ...validatedContent, requestId: response?.requestId });
1954
2032
  return validatedContent;
1955
2033
  }).catch((error) => {
1956
2034
  this.status = "failed";
@@ -1970,17 +2048,7 @@ class CanvasExecution extends Emittery {
1970
2048
  */
1971
2049
  async startAsync() {
1972
2050
  const resolvedVariables = await this.resolveVariables();
1973
- const body = {
1974
- async: true,
1975
- stream: false,
1976
- ...this.baseBody,
1977
- variables: resolvedVariables
1978
- };
1979
- return await this._client.post("/v2/chat/completions", {
1980
- body,
1981
- stream: false,
1982
- signal: this._abortController.signal
1983
- }).then((response) => {
2051
+ return await this.create(resolvedVariables, { async: true }).then((response) => {
1984
2052
  this._id = response.id;
1985
2053
  this.status = response.status;
1986
2054
  this.emit("poll", {
@@ -1988,7 +2056,7 @@ class CanvasExecution extends Emittery {
1988
2056
  status: response.status,
1989
2057
  outputContent: response.output_content,
1990
2058
  rawOutput: response.raw_output,
1991
- headers: response.headers
2059
+ requestId: response.requestId
1992
2060
  });
1993
2061
  return response;
1994
2062
  });
@@ -2000,16 +2068,7 @@ class CanvasExecution extends Emittery {
2000
2068
  */
2001
2069
  async startStream() {
2002
2070
  const resolvedVariables = await this.resolveVariables();
2003
- const body = {
2004
- ...this.baseBody,
2005
- stream: true,
2006
- variables: resolvedVariables
2007
- };
2008
- this._stream = await this._client.post("/v2/chat/completions", {
2009
- body,
2010
- stream: true,
2011
- signal: this._abortController.signal
2012
- });
2071
+ this._stream = await this.create(resolvedVariables, { stream: true });
2013
2072
  this.status = "streaming";
2014
2073
  return this._stream;
2015
2074
  }
@@ -2053,7 +2112,7 @@ class CanvasExecution extends Emittery {
2053
2112
  };
2054
2113
  }
2055
2114
  this._rawResultValue = response;
2056
- this.emit("success", { ...getResultFromPollingResponse(response), headers: response?.headers ?? {} });
2115
+ this.emit("success", { ...getResultFromPollingResponse(response), requestId: response?.requestId });
2057
2116
  return {
2058
2117
  done: response.status === "succeeded",
2059
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.1",
3
+ "version": "2.3.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/meistrari/tela-sdk-js.git"