@alquimia-ai/tools 2.4.0 → 2.5.0

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.
Files changed (76) hide show
  1. package/README.md +6 -0
  2. package/dist/actions/index.d.mts +2 -2
  3. package/dist/actions/index.d.ts +2 -2
  4. package/dist/actions/index.js +1 -1
  5. package/dist/actions/index.js.map +1 -1
  6. package/dist/actions/index.mjs +1 -1
  7. package/dist/actions/index.mjs.map +1 -1
  8. package/dist/{actions-CZU_GRy5.d.mts → actions-BjDPJdyA.d.mts} +1 -1
  9. package/dist/{actions-B0hfoYRd.d.ts → actions-CP1d4Ye1.d.ts} +1 -1
  10. package/dist/adapters/index.d.mts +2 -2
  11. package/dist/adapters/index.d.ts +2 -2
  12. package/dist/adapters/index.js.map +1 -1
  13. package/dist/genui/index.d.mts +3 -3
  14. package/dist/genui/index.d.ts +3 -3
  15. package/dist/genui/index.js +9 -1
  16. package/dist/genui/index.js.map +1 -1
  17. package/dist/genui/index.mjs +9 -1
  18. package/dist/genui/index.mjs.map +1 -1
  19. package/dist/hooks/index.d.mts +10 -10
  20. package/dist/hooks/index.d.ts +10 -10
  21. package/dist/hooks/index.js +28 -8
  22. package/dist/hooks/index.js.map +1 -1
  23. package/dist/hooks/index.mjs +28 -8
  24. package/dist/hooks/index.mjs.map +1 -1
  25. package/dist/next/index.js +19 -5
  26. package/dist/next/index.js.map +1 -1
  27. package/dist/next/index.mjs +19 -5
  28. package/dist/next/index.mjs.map +1 -1
  29. package/dist/providers/index.d.mts +4 -4
  30. package/dist/providers/index.d.ts +4 -4
  31. package/dist/providers/index.js +111 -110
  32. package/dist/providers/index.js.map +1 -1
  33. package/dist/providers/index.mjs +111 -110
  34. package/dist/providers/index.mjs.map +1 -1
  35. package/dist/{providers-BJTXCtI3.d.ts → providers-DiR9cgyo.d.mts} +8 -8
  36. package/dist/{providers-0Gi78uNQ.d.mts → providers-b5_yMyMo.d.ts} +8 -8
  37. package/dist/proxy.d.mts +4 -4
  38. package/dist/proxy.d.ts +4 -4
  39. package/dist/proxy.js +19 -5
  40. package/dist/proxy.js.map +1 -1
  41. package/dist/proxy.mjs +19 -5
  42. package/dist/proxy.mjs.map +1 -1
  43. package/dist/sdk/index.d.mts +4 -3
  44. package/dist/sdk/index.d.ts +4 -3
  45. package/dist/sdk/index.js +8 -2
  46. package/dist/sdk/index.js.map +1 -1
  47. package/dist/sdk/index.mjs +8 -2
  48. package/dist/sdk/index.mjs.map +1 -1
  49. package/dist/services/index.d.mts +3 -3
  50. package/dist/services/index.d.ts +3 -3
  51. package/dist/services/index.js.map +1 -1
  52. package/dist/services/index.mjs.map +1 -1
  53. package/dist/type-DqX3-9QS.d.mts +312 -0
  54. package/dist/type-xksRnBUW.d.ts +312 -0
  55. package/dist/types/index.d.mts +78 -304
  56. package/dist/types/index.d.ts +78 -304
  57. package/dist/types/index.js.map +1 -1
  58. package/dist/types-C-6fgK1_.d.mts +111 -0
  59. package/dist/types-C-6fgK1_.d.ts +111 -0
  60. package/dist/{types-DnfWUE9V.d.mts → types-CMVbyEv8.d.mts} +3 -2
  61. package/dist/{types-DnfWUE9V.d.ts → types-CMVbyEv8.d.ts} +3 -2
  62. package/dist/utils/index.d.mts +2 -2
  63. package/dist/utils/index.d.ts +2 -2
  64. package/dist/utils/index.js +1 -1
  65. package/dist/utils/index.js.map +1 -1
  66. package/dist/utils/index.mjs +1 -1
  67. package/dist/utils/index.mjs.map +1 -1
  68. package/dist/worklog/index.d.mts +5 -2
  69. package/dist/worklog/index.d.ts +5 -2
  70. package/dist/worklog/index.js +3 -1
  71. package/dist/worklog/index.js.map +1 -1
  72. package/dist/worklog/index.mjs +3 -1
  73. package/dist/worklog/index.mjs.map +1 -1
  74. package/package.json +1 -1
  75. package/dist/types-Dvu9y4WM.d.mts +0 -53
  76. package/dist/types-Dvu9y4WM.d.ts +0 -53
@@ -1,4 +1,4 @@
1
- import { TTSResult } from './types/index.js';
1
+ import { T as TTSResult } from './type-DqX3-9QS.mjs';
2
2
 
3
3
  declare abstract class GenerativeProvider {
4
4
  private config;
@@ -7,29 +7,29 @@ declare abstract class GenerativeProvider {
7
7
  declare abstract class WhisperProvider {
8
8
  protected config: Record<string, any>;
9
9
  constructor(config: Record<string, any>);
10
- abstract textToSpeech(text: string): Promise<TTSResult>;
11
- abstract speechToText(audio: string): Promise<string>;
10
+ abstract textToSpeech(_text: string): Promise<TTSResult>;
11
+ abstract speechToText(_audio: string): Promise<string>;
12
12
  }
13
13
  declare abstract class StableDiffusionProvider {
14
14
  protected config: Record<string, any>;
15
15
  constructor(config: Record<string, any>);
16
- abstract generateImage(query: string): Promise<string>;
16
+ abstract generateImage(_query: string): Promise<string>;
17
17
  }
18
18
  declare abstract class CharacterizationProvider {
19
19
  protected config: Record<string, any>;
20
20
  constructor(config: Record<string, any>);
21
- abstract analyzeCharacterization(text: string): Promise<Record<string, any>>;
21
+ abstract analyzeCharacterization(_text: string): Promise<Record<string, any>>;
22
22
  }
23
23
  declare abstract class RatingsProvider {
24
24
  protected config: Record<string, any>;
25
25
  constructor(config: Record<string, any>);
26
- abstract rate(data: Record<string, any>): Promise<Record<string, any>>;
26
+ abstract rate(_data: Record<string, any>): Promise<Record<string, any>>;
27
27
  }
28
28
  declare abstract class LoggerProvider {
29
29
  protected config: Record<string, any>;
30
30
  constructor(config: Record<string, any>);
31
- abstract logInfo(message: string, data?: Record<string, any>): void;
32
- abstract logError(message: string, error: Error, data?: Record<string, any>): void;
31
+ abstract logInfo(_message: string, _data?: Record<string, any>): void;
32
+ abstract logError(_message: string, _error: Error, _data?: Record<string, any>): void;
33
33
  }
34
34
 
35
35
  export { CharacterizationProvider as C, GenerativeProvider as G, LoggerProvider as L, RatingsProvider as R, StableDiffusionProvider as S, WhisperProvider as W };
@@ -1,4 +1,4 @@
1
- import { TTSResult } from './types/index.mjs';
1
+ import { T as TTSResult } from './type-xksRnBUW.js';
2
2
 
3
3
  declare abstract class GenerativeProvider {
4
4
  private config;
@@ -7,29 +7,29 @@ declare abstract class GenerativeProvider {
7
7
  declare abstract class WhisperProvider {
8
8
  protected config: Record<string, any>;
9
9
  constructor(config: Record<string, any>);
10
- abstract textToSpeech(text: string): Promise<TTSResult>;
11
- abstract speechToText(audio: string): Promise<string>;
10
+ abstract textToSpeech(_text: string): Promise<TTSResult>;
11
+ abstract speechToText(_audio: string): Promise<string>;
12
12
  }
13
13
  declare abstract class StableDiffusionProvider {
14
14
  protected config: Record<string, any>;
15
15
  constructor(config: Record<string, any>);
16
- abstract generateImage(query: string): Promise<string>;
16
+ abstract generateImage(_query: string): Promise<string>;
17
17
  }
18
18
  declare abstract class CharacterizationProvider {
19
19
  protected config: Record<string, any>;
20
20
  constructor(config: Record<string, any>);
21
- abstract analyzeCharacterization(text: string): Promise<Record<string, any>>;
21
+ abstract analyzeCharacterization(_text: string): Promise<Record<string, any>>;
22
22
  }
23
23
  declare abstract class RatingsProvider {
24
24
  protected config: Record<string, any>;
25
25
  constructor(config: Record<string, any>);
26
- abstract rate(data: Record<string, any>): Promise<Record<string, any>>;
26
+ abstract rate(_data: Record<string, any>): Promise<Record<string, any>>;
27
27
  }
28
28
  declare abstract class LoggerProvider {
29
29
  protected config: Record<string, any>;
30
30
  constructor(config: Record<string, any>);
31
- abstract logInfo(message: string, data?: Record<string, any>): void;
32
- abstract logError(message: string, error: Error, data?: Record<string, any>): void;
31
+ abstract logInfo(_message: string, _data?: Record<string, any>): void;
32
+ abstract logError(_message: string, _error: Error, _data?: Record<string, any>): void;
33
33
  }
34
34
 
35
35
  export { CharacterizationProvider as C, GenerativeProvider as G, LoggerProvider as L, RatingsProvider as R, StableDiffusionProvider as S, WhisperProvider as W };
package/dist/proxy.d.mts CHANGED
@@ -7,10 +7,10 @@ interface ProxyConfig {
7
7
  toolCompletionRoute?: string;
8
8
  }
9
9
  interface AlquimiaProxyHandler {
10
- handleInfer(request: Request, pathSuffix: string): Promise<Response>;
11
- handleStream(request: Request, pathSuffix: string): Promise<Response>;
12
- handleBlobUpload(request: Request): Promise<Response>;
13
- handleToolCompletion(request: Request): Promise<Response>;
10
+ handleInfer(_request: Request, _pathSuffix: string): Promise<Response>;
11
+ handleStream(_request: Request, _pathSuffix: string): Promise<Response>;
12
+ handleBlobUpload(_request: Request): Promise<Response>;
13
+ handleToolCompletion(_request: Request): Promise<Response>;
14
14
  }
15
15
  declare function createAlquimiaProxyHandler(config: ProxyConfig): AlquimiaProxyHandler;
16
16
 
package/dist/proxy.d.ts CHANGED
@@ -7,10 +7,10 @@ interface ProxyConfig {
7
7
  toolCompletionRoute?: string;
8
8
  }
9
9
  interface AlquimiaProxyHandler {
10
- handleInfer(request: Request, pathSuffix: string): Promise<Response>;
11
- handleStream(request: Request, pathSuffix: string): Promise<Response>;
12
- handleBlobUpload(request: Request): Promise<Response>;
13
- handleToolCompletion(request: Request): Promise<Response>;
10
+ handleInfer(_request: Request, _pathSuffix: string): Promise<Response>;
11
+ handleStream(_request: Request, _pathSuffix: string): Promise<Response>;
12
+ handleBlobUpload(_request: Request): Promise<Response>;
13
+ handleToolCompletion(_request: Request): Promise<Response>;
14
14
  }
15
15
  declare function createAlquimiaProxyHandler(config: ProxyConfig): AlquimiaProxyHandler;
16
16
 
package/dist/proxy.js CHANGED
@@ -41,6 +41,13 @@ function pickIdentityHeaders(request) {
41
41
  }
42
42
  return out;
43
43
  }
44
+ function pickTraceHeader(request) {
45
+ const fromHeader = request.headers.get("x-trace-parent");
46
+ if (fromHeader) return { "x-trace-parent": fromHeader };
47
+ const fromQuery = new URL(request.url).searchParams.get("trace_parent");
48
+ if (fromQuery) return { "x-trace-parent": fromQuery };
49
+ return {};
50
+ }
44
51
  function createAlquimiaProxyHandler(config) {
45
52
  const baseUrl = config.assistantBaseUrl.replace(/\/$/, "");
46
53
  const inferRoute = config.inferRoute ?? "event/infer";
@@ -60,7 +67,9 @@ function createAlquimiaProxyHandler(config) {
60
67
  method: "POST",
61
68
  headers: {
62
69
  "Content-Type": "application/json",
63
- ...authHeader
70
+ ...authHeader,
71
+ ...pickIdentityHeaders(request),
72
+ ...pickTraceHeader(request)
64
73
  },
65
74
  body: JSON.stringify(body)
66
75
  });
@@ -100,7 +109,12 @@ function createAlquimiaProxyHandler(config) {
100
109
  try {
101
110
  const targetUrl = `${baseUrl}/${streamRoute}/${pathSuffix}`;
102
111
  const response = await fetch(targetUrl, {
103
- headers: { "Content-Type": "application/json", ...authHeader }
112
+ headers: {
113
+ "Content-Type": "application/json",
114
+ ...authHeader,
115
+ ...pickIdentityHeaders(request),
116
+ ...pickTraceHeader(request)
117
+ }
104
118
  });
105
119
  if (!response.ok) {
106
120
  const errorJson = await response.json().catch(() => ({}));
@@ -142,7 +156,8 @@ function createAlquimiaProxyHandler(config) {
142
156
  headers: {
143
157
  ...authHeader,
144
158
  ...contentType && { "Content-Type": contentType },
145
- ...pickIdentityHeaders(request)
159
+ ...pickIdentityHeaders(request),
160
+ ...pickTraceHeader(request)
146
161
  },
147
162
  body: request.body,
148
163
  duplex: "half"
@@ -187,8 +202,7 @@ function createAlquimiaProxyHandler(config) {
187
202
  const value = request.headers.get(name);
188
203
  if (value) headers[name] = value;
189
204
  }
190
- const trace = request.headers.get("x-trace-parent");
191
- if (trace) headers["x-trace-parent"] = trace;
205
+ Object.assign(headers, pickTraceHeader(request));
192
206
  const response = await fetch(`${baseUrl}/${toolCompletionRoute}`, {
193
207
  method: "POST",
194
208
  headers,
package/dist/proxy.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/proxy.ts"],"sourcesContent":["export interface ProxyConfig {\n assistantBaseUrl: string;\n apiKey: string;\n inferRoute?: string; // default: 'event/infer'\n streamRoute?: string; // default: 'event/stream'\n blobUploadRoute?: string; // default: 'context/blob/upload'\n toolCompletionRoute?: string; // default: 'event/tool-completion'\n}\n\nexport interface AlquimiaProxyHandler {\n handleInfer(request: Request, pathSuffix: string): Promise<Response>;\n handleStream(request: Request, pathSuffix: string): Promise<Response>;\n handleBlobUpload(request: Request): Promise<Response>;\n handleToolCompletion(request: Request): Promise<Response>;\n}\n\nconst IDENTITY_HEADER_NAMES = [\n 'task-id',\n 'parent-task-id',\n 'session-id',\n 'user-id',\n 'assistant-id',\n 'agentspace-id',\n 'channel-id',\n 'depth',\n] as const;\n\nfunction pickIdentityHeaders(request: Request): Record<string, string> {\n const out: Record<string, string> = {};\n for (const name of IDENTITY_HEADER_NAMES) {\n const value = request.headers.get(name);\n if (value) out[name] = value;\n }\n return out;\n}\n\nexport function createAlquimiaProxyHandler(config: ProxyConfig): AlquimiaProxyHandler {\n const baseUrl = config.assistantBaseUrl.replace(/\\/$/, '');\n const inferRoute = config.inferRoute ?? 'event/infer';\n const streamRoute = config.streamRoute ?? 'event/stream';\n const blobUploadRoute = config.blobUploadRoute ?? 'context/blob/upload';\n const toolCompletionRoute = config.toolCompletionRoute ?? 'event/tool-completion';\n const authHeader = { Authorization: `Bearer ${config.apiKey}` };\n\n return {\n async handleInfer(request: Request, pathSuffix: string): Promise<Response> {\n try {\n const body = await request.json();\n const url = new URL(request.url);\n const querySuffix = url.searchParams.toString()\n ? `?${url.searchParams.toString()}`\n : '';\n const slug = pathSuffix.replace(/^\\/+|\\/+$/g, '');\n const targetUrl = `${baseUrl}/${inferRoute}/${slug}${querySuffix}`;\n\n\n const response = await fetch(targetUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...authHeader,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorJson = await response.json().catch(() => ({}));\n console.error('AlquimiaProxy handleInfer error:', {\n status: response.status,\n statusText: response.statusText,\n body: errorJson,\n });\n return new Response(\n JSON.stringify({\n status: response.status,\n statusText: response.statusText,\n ...errorJson,\n }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n return new Response(response.body, {\n status: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Content-Encoding',\n },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleInfer exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward infer request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleStream(request: Request, pathSuffix: string): Promise<Response> {\n try {\n const targetUrl = `${baseUrl}/${streamRoute}/${pathSuffix}`;\n\n const response = await fetch(targetUrl, {\n headers: { 'Content-Type': 'application/json', ...authHeader },\n });\n\n if (!response.ok) {\n const errorJson = await response.json().catch(() => ({}));\n console.error('AlquimiaProxy handleStream error:', {\n status: response.status,\n statusText: response.statusText,\n body: errorJson,\n });\n return new Response(\n JSON.stringify({\n error: errorJson.message || response.statusText || 'Failed to forward stream',\n ...errorJson,\n }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n return new Response(response.body, {\n status: 200,\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleStream exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward stream request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleBlobUpload(request: Request): Promise<Response> {\n try {\n const targetUrl = `${baseUrl}/${blobUploadRoute}`;\n const contentType = request.headers.get('Content-Type') ?? '';\n\n const response = await fetch(targetUrl, {\n method: 'POST',\n headers: {\n ...authHeader,\n ...(contentType && { 'Content-Type': contentType }),\n ...pickIdentityHeaders(request),\n },\n body: request.body,\n duplex: 'half',\n } as RequestInit);\n\n if (!response.ok) {\n return new Response(\n JSON.stringify({ error: 'Failed to upload blob', status: response.status }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const responseText = await response.text();\n return new Response(responseText, {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleBlobUpload exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward blob upload request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleToolCompletion(request: Request): Promise<Response> {\n try {\n const body = await request.text();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...authHeader,\n };\n // Forward the runtime's tool-completion correlation headers verbatim\n // (non-hyphenated names, per the runtime OpenAPI). These route the\n // completion to the parked task so the SSE stream resumes.\n const CORRELATION_HEADERS = [\n 'taskid',\n 'parenttaskid',\n 'sessionid',\n 'userid',\n 'assistantid',\n 'agentspaceid',\n 'channelid',\n 'depth',\n ];\n for (const name of CORRELATION_HEADERS) {\n const value = request.headers.get(name);\n if (value) headers[name] = value;\n }\n const trace = request.headers.get('x-trace-parent');\n if (trace) headers['x-trace-parent'] = trace;\n\n const response = await fetch(`${baseUrl}/${toolCompletionRoute}`, {\n method: 'POST',\n headers,\n body,\n });\n\n return new Response(await response.text(), {\n status: response.status,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleToolCompletion exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward tool-completion request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/proxy.ts"],"sourcesContent":["export interface ProxyConfig {\n assistantBaseUrl: string;\n apiKey: string;\n inferRoute?: string; // default: 'event/infer'\n streamRoute?: string; // default: 'event/stream'\n blobUploadRoute?: string; // default: 'context/blob/upload'\n toolCompletionRoute?: string; // default: 'event/tool-completion'\n}\n\nexport interface AlquimiaProxyHandler {\n handleInfer(_request: Request, _pathSuffix: string): Promise<Response>;\n handleStream(_request: Request, _pathSuffix: string): Promise<Response>;\n handleBlobUpload(_request: Request): Promise<Response>;\n handleToolCompletion(_request: Request): Promise<Response>;\n}\n\nconst IDENTITY_HEADER_NAMES = [\n 'task-id',\n 'parent-task-id',\n 'session-id',\n 'user-id',\n 'assistant-id',\n 'agentspace-id',\n 'channel-id',\n 'depth',\n] as const;\n\nfunction pickIdentityHeaders(request: Request): Record<string, string> {\n const out: Record<string, string> = {};\n for (const name of IDENTITY_HEADER_NAMES) {\n const value = request.headers.get(name);\n if (value) out[name] = value;\n }\n return out;\n}\n\n/**\n * Trace-context propagation. The proxy builds a fresh request against the\n * runtime, so anything the caller set is dropped unless it is copied over\n * explicitly — which is how `x-trace-parent` stopped reaching the runtime when\n * the direct-to-runtime client was replaced by this proxy.\n *\n * The header is the transport wherever the caller can set one. `EventSource`\n * cannot, so the stream route also accepts the same value as a `trace_parent`\n * query param.\n */\nfunction pickTraceHeader(request: Request): Record<string, string> {\n const fromHeader = request.headers.get('x-trace-parent');\n if (fromHeader) return { 'x-trace-parent': fromHeader };\n\n const fromQuery = new URL(request.url).searchParams.get('trace_parent');\n if (fromQuery) return { 'x-trace-parent': fromQuery };\n\n return {};\n}\n\nexport function createAlquimiaProxyHandler(config: ProxyConfig): AlquimiaProxyHandler {\n const baseUrl = config.assistantBaseUrl.replace(/\\/$/, '');\n const inferRoute = config.inferRoute ?? 'event/infer';\n const streamRoute = config.streamRoute ?? 'event/stream';\n const blobUploadRoute = config.blobUploadRoute ?? 'context/blob/upload';\n const toolCompletionRoute = config.toolCompletionRoute ?? 'event/tool-completion';\n const authHeader = { Authorization: `Bearer ${config.apiKey}` };\n\n return {\n async handleInfer(request: Request, pathSuffix: string): Promise<Response> {\n try {\n const body = await request.json();\n const url = new URL(request.url);\n const querySuffix = url.searchParams.toString()\n ? `?${url.searchParams.toString()}`\n : '';\n const slug = pathSuffix.replace(/^\\/+|\\/+$/g, '');\n const targetUrl = `${baseUrl}/${inferRoute}/${slug}${querySuffix}`;\n\n\n const response = await fetch(targetUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...authHeader,\n ...pickIdentityHeaders(request),\n ...pickTraceHeader(request),\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorJson = await response.json().catch(() => ({}));\n console.error('AlquimiaProxy handleInfer error:', {\n status: response.status,\n statusText: response.statusText,\n body: errorJson,\n });\n return new Response(\n JSON.stringify({\n status: response.status,\n statusText: response.statusText,\n ...errorJson,\n }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n return new Response(response.body, {\n status: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Content-Encoding',\n },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleInfer exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward infer request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleStream(request: Request, pathSuffix: string): Promise<Response> {\n try {\n const targetUrl = `${baseUrl}/${streamRoute}/${pathSuffix}`;\n\n const response = await fetch(targetUrl, {\n headers: {\n 'Content-Type': 'application/json',\n ...authHeader,\n ...pickIdentityHeaders(request),\n ...pickTraceHeader(request),\n },\n });\n\n if (!response.ok) {\n const errorJson = await response.json().catch(() => ({}));\n console.error('AlquimiaProxy handleStream error:', {\n status: response.status,\n statusText: response.statusText,\n body: errorJson,\n });\n return new Response(\n JSON.stringify({\n error: errorJson.message || response.statusText || 'Failed to forward stream',\n ...errorJson,\n }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n return new Response(response.body, {\n status: 200,\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleStream exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward stream request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleBlobUpload(request: Request): Promise<Response> {\n try {\n const targetUrl = `${baseUrl}/${blobUploadRoute}`;\n const contentType = request.headers.get('Content-Type') ?? '';\n\n const response = await fetch(targetUrl, {\n method: 'POST',\n headers: {\n ...authHeader,\n ...(contentType && { 'Content-Type': contentType }),\n ...pickIdentityHeaders(request),\n ...pickTraceHeader(request),\n },\n body: request.body,\n duplex: 'half',\n } as RequestInit);\n\n if (!response.ok) {\n return new Response(\n JSON.stringify({ error: 'Failed to upload blob', status: response.status }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const responseText = await response.text();\n return new Response(responseText, {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleBlobUpload exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward blob upload request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleToolCompletion(request: Request): Promise<Response> {\n try {\n const body = await request.text();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...authHeader,\n };\n // Forward the runtime's tool-completion correlation headers verbatim\n // (non-hyphenated names, per the runtime OpenAPI). These route the\n // completion to the parked task so the SSE stream resumes.\n const CORRELATION_HEADERS = [\n 'taskid',\n 'parenttaskid',\n 'sessionid',\n 'userid',\n 'assistantid',\n 'agentspaceid',\n 'channelid',\n 'depth',\n ];\n for (const name of CORRELATION_HEADERS) {\n const value = request.headers.get(name);\n if (value) headers[name] = value;\n }\n Object.assign(headers, pickTraceHeader(request));\n\n const response = await fetch(`${baseUrl}/${toolCompletionRoute}`, {\n method: 'POST',\n headers,\n body,\n });\n\n return new Response(await response.text(), {\n status: response.status,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleToolCompletion exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward tool-completion request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n };\n}\n"],"mappings":"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","names":[]}
package/dist/proxy.mjs CHANGED
@@ -17,6 +17,13 @@ function pickIdentityHeaders(request) {
17
17
  }
18
18
  return out;
19
19
  }
20
+ function pickTraceHeader(request) {
21
+ const fromHeader = request.headers.get("x-trace-parent");
22
+ if (fromHeader) return { "x-trace-parent": fromHeader };
23
+ const fromQuery = new URL(request.url).searchParams.get("trace_parent");
24
+ if (fromQuery) return { "x-trace-parent": fromQuery };
25
+ return {};
26
+ }
20
27
  function createAlquimiaProxyHandler(config) {
21
28
  const baseUrl = config.assistantBaseUrl.replace(/\/$/, "");
22
29
  const inferRoute = config.inferRoute ?? "event/infer";
@@ -36,7 +43,9 @@ function createAlquimiaProxyHandler(config) {
36
43
  method: "POST",
37
44
  headers: {
38
45
  "Content-Type": "application/json",
39
- ...authHeader
46
+ ...authHeader,
47
+ ...pickIdentityHeaders(request),
48
+ ...pickTraceHeader(request)
40
49
  },
41
50
  body: JSON.stringify(body)
42
51
  });
@@ -76,7 +85,12 @@ function createAlquimiaProxyHandler(config) {
76
85
  try {
77
86
  const targetUrl = `${baseUrl}/${streamRoute}/${pathSuffix}`;
78
87
  const response = await fetch(targetUrl, {
79
- headers: { "Content-Type": "application/json", ...authHeader }
88
+ headers: {
89
+ "Content-Type": "application/json",
90
+ ...authHeader,
91
+ ...pickIdentityHeaders(request),
92
+ ...pickTraceHeader(request)
93
+ }
80
94
  });
81
95
  if (!response.ok) {
82
96
  const errorJson = await response.json().catch(() => ({}));
@@ -118,7 +132,8 @@ function createAlquimiaProxyHandler(config) {
118
132
  headers: {
119
133
  ...authHeader,
120
134
  ...contentType && { "Content-Type": contentType },
121
- ...pickIdentityHeaders(request)
135
+ ...pickIdentityHeaders(request),
136
+ ...pickTraceHeader(request)
122
137
  },
123
138
  body: request.body,
124
139
  duplex: "half"
@@ -163,8 +178,7 @@ function createAlquimiaProxyHandler(config) {
163
178
  const value = request.headers.get(name);
164
179
  if (value) headers[name] = value;
165
180
  }
166
- const trace = request.headers.get("x-trace-parent");
167
- if (trace) headers["x-trace-parent"] = trace;
181
+ Object.assign(headers, pickTraceHeader(request));
168
182
  const response = await fetch(`${baseUrl}/${toolCompletionRoute}`, {
169
183
  method: "POST",
170
184
  headers,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/proxy.ts"],"sourcesContent":["export interface ProxyConfig {\n assistantBaseUrl: string;\n apiKey: string;\n inferRoute?: string; // default: 'event/infer'\n streamRoute?: string; // default: 'event/stream'\n blobUploadRoute?: string; // default: 'context/blob/upload'\n toolCompletionRoute?: string; // default: 'event/tool-completion'\n}\n\nexport interface AlquimiaProxyHandler {\n handleInfer(request: Request, pathSuffix: string): Promise<Response>;\n handleStream(request: Request, pathSuffix: string): Promise<Response>;\n handleBlobUpload(request: Request): Promise<Response>;\n handleToolCompletion(request: Request): Promise<Response>;\n}\n\nconst IDENTITY_HEADER_NAMES = [\n 'task-id',\n 'parent-task-id',\n 'session-id',\n 'user-id',\n 'assistant-id',\n 'agentspace-id',\n 'channel-id',\n 'depth',\n] as const;\n\nfunction pickIdentityHeaders(request: Request): Record<string, string> {\n const out: Record<string, string> = {};\n for (const name of IDENTITY_HEADER_NAMES) {\n const value = request.headers.get(name);\n if (value) out[name] = value;\n }\n return out;\n}\n\nexport function createAlquimiaProxyHandler(config: ProxyConfig): AlquimiaProxyHandler {\n const baseUrl = config.assistantBaseUrl.replace(/\\/$/, '');\n const inferRoute = config.inferRoute ?? 'event/infer';\n const streamRoute = config.streamRoute ?? 'event/stream';\n const blobUploadRoute = config.blobUploadRoute ?? 'context/blob/upload';\n const toolCompletionRoute = config.toolCompletionRoute ?? 'event/tool-completion';\n const authHeader = { Authorization: `Bearer ${config.apiKey}` };\n\n return {\n async handleInfer(request: Request, pathSuffix: string): Promise<Response> {\n try {\n const body = await request.json();\n const url = new URL(request.url);\n const querySuffix = url.searchParams.toString()\n ? `?${url.searchParams.toString()}`\n : '';\n const slug = pathSuffix.replace(/^\\/+|\\/+$/g, '');\n const targetUrl = `${baseUrl}/${inferRoute}/${slug}${querySuffix}`;\n\n\n const response = await fetch(targetUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...authHeader,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorJson = await response.json().catch(() => ({}));\n console.error('AlquimiaProxy handleInfer error:', {\n status: response.status,\n statusText: response.statusText,\n body: errorJson,\n });\n return new Response(\n JSON.stringify({\n status: response.status,\n statusText: response.statusText,\n ...errorJson,\n }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n return new Response(response.body, {\n status: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Content-Encoding',\n },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleInfer exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward infer request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleStream(request: Request, pathSuffix: string): Promise<Response> {\n try {\n const targetUrl = `${baseUrl}/${streamRoute}/${pathSuffix}`;\n\n const response = await fetch(targetUrl, {\n headers: { 'Content-Type': 'application/json', ...authHeader },\n });\n\n if (!response.ok) {\n const errorJson = await response.json().catch(() => ({}));\n console.error('AlquimiaProxy handleStream error:', {\n status: response.status,\n statusText: response.statusText,\n body: errorJson,\n });\n return new Response(\n JSON.stringify({\n error: errorJson.message || response.statusText || 'Failed to forward stream',\n ...errorJson,\n }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n return new Response(response.body, {\n status: 200,\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleStream exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward stream request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleBlobUpload(request: Request): Promise<Response> {\n try {\n const targetUrl = `${baseUrl}/${blobUploadRoute}`;\n const contentType = request.headers.get('Content-Type') ?? '';\n\n const response = await fetch(targetUrl, {\n method: 'POST',\n headers: {\n ...authHeader,\n ...(contentType && { 'Content-Type': contentType }),\n ...pickIdentityHeaders(request),\n },\n body: request.body,\n duplex: 'half',\n } as RequestInit);\n\n if (!response.ok) {\n return new Response(\n JSON.stringify({ error: 'Failed to upload blob', status: response.status }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const responseText = await response.text();\n return new Response(responseText, {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleBlobUpload exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward blob upload request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleToolCompletion(request: Request): Promise<Response> {\n try {\n const body = await request.text();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...authHeader,\n };\n // Forward the runtime's tool-completion correlation headers verbatim\n // (non-hyphenated names, per the runtime OpenAPI). These route the\n // completion to the parked task so the SSE stream resumes.\n const CORRELATION_HEADERS = [\n 'taskid',\n 'parenttaskid',\n 'sessionid',\n 'userid',\n 'assistantid',\n 'agentspaceid',\n 'channelid',\n 'depth',\n ];\n for (const name of CORRELATION_HEADERS) {\n const value = request.headers.get(name);\n if (value) headers[name] = value;\n }\n const trace = request.headers.get('x-trace-parent');\n if (trace) headers['x-trace-parent'] = trace;\n\n const response = await fetch(`${baseUrl}/${toolCompletionRoute}`, {\n method: 'POST',\n headers,\n body,\n });\n\n return new Response(await response.text(), {\n status: response.status,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleToolCompletion exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward tool-completion request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/proxy.ts"],"sourcesContent":["export interface ProxyConfig {\n assistantBaseUrl: string;\n apiKey: string;\n inferRoute?: string; // default: 'event/infer'\n streamRoute?: string; // default: 'event/stream'\n blobUploadRoute?: string; // default: 'context/blob/upload'\n toolCompletionRoute?: string; // default: 'event/tool-completion'\n}\n\nexport interface AlquimiaProxyHandler {\n handleInfer(_request: Request, _pathSuffix: string): Promise<Response>;\n handleStream(_request: Request, _pathSuffix: string): Promise<Response>;\n handleBlobUpload(_request: Request): Promise<Response>;\n handleToolCompletion(_request: Request): Promise<Response>;\n}\n\nconst IDENTITY_HEADER_NAMES = [\n 'task-id',\n 'parent-task-id',\n 'session-id',\n 'user-id',\n 'assistant-id',\n 'agentspace-id',\n 'channel-id',\n 'depth',\n] as const;\n\nfunction pickIdentityHeaders(request: Request): Record<string, string> {\n const out: Record<string, string> = {};\n for (const name of IDENTITY_HEADER_NAMES) {\n const value = request.headers.get(name);\n if (value) out[name] = value;\n }\n return out;\n}\n\n/**\n * Trace-context propagation. The proxy builds a fresh request against the\n * runtime, so anything the caller set is dropped unless it is copied over\n * explicitly — which is how `x-trace-parent` stopped reaching the runtime when\n * the direct-to-runtime client was replaced by this proxy.\n *\n * The header is the transport wherever the caller can set one. `EventSource`\n * cannot, so the stream route also accepts the same value as a `trace_parent`\n * query param.\n */\nfunction pickTraceHeader(request: Request): Record<string, string> {\n const fromHeader = request.headers.get('x-trace-parent');\n if (fromHeader) return { 'x-trace-parent': fromHeader };\n\n const fromQuery = new URL(request.url).searchParams.get('trace_parent');\n if (fromQuery) return { 'x-trace-parent': fromQuery };\n\n return {};\n}\n\nexport function createAlquimiaProxyHandler(config: ProxyConfig): AlquimiaProxyHandler {\n const baseUrl = config.assistantBaseUrl.replace(/\\/$/, '');\n const inferRoute = config.inferRoute ?? 'event/infer';\n const streamRoute = config.streamRoute ?? 'event/stream';\n const blobUploadRoute = config.blobUploadRoute ?? 'context/blob/upload';\n const toolCompletionRoute = config.toolCompletionRoute ?? 'event/tool-completion';\n const authHeader = { Authorization: `Bearer ${config.apiKey}` };\n\n return {\n async handleInfer(request: Request, pathSuffix: string): Promise<Response> {\n try {\n const body = await request.json();\n const url = new URL(request.url);\n const querySuffix = url.searchParams.toString()\n ? `?${url.searchParams.toString()}`\n : '';\n const slug = pathSuffix.replace(/^\\/+|\\/+$/g, '');\n const targetUrl = `${baseUrl}/${inferRoute}/${slug}${querySuffix}`;\n\n\n const response = await fetch(targetUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...authHeader,\n ...pickIdentityHeaders(request),\n ...pickTraceHeader(request),\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorJson = await response.json().catch(() => ({}));\n console.error('AlquimiaProxy handleInfer error:', {\n status: response.status,\n statusText: response.statusText,\n body: errorJson,\n });\n return new Response(\n JSON.stringify({\n status: response.status,\n statusText: response.statusText,\n ...errorJson,\n }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n return new Response(response.body, {\n status: 200,\n headers: {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Content-Encoding',\n },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleInfer exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward infer request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleStream(request: Request, pathSuffix: string): Promise<Response> {\n try {\n const targetUrl = `${baseUrl}/${streamRoute}/${pathSuffix}`;\n\n const response = await fetch(targetUrl, {\n headers: {\n 'Content-Type': 'application/json',\n ...authHeader,\n ...pickIdentityHeaders(request),\n ...pickTraceHeader(request),\n },\n });\n\n if (!response.ok) {\n const errorJson = await response.json().catch(() => ({}));\n console.error('AlquimiaProxy handleStream error:', {\n status: response.status,\n statusText: response.statusText,\n body: errorJson,\n });\n return new Response(\n JSON.stringify({\n error: errorJson.message || response.statusText || 'Failed to forward stream',\n ...errorJson,\n }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n return new Response(response.body, {\n status: 200,\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleStream exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward stream request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleBlobUpload(request: Request): Promise<Response> {\n try {\n const targetUrl = `${baseUrl}/${blobUploadRoute}`;\n const contentType = request.headers.get('Content-Type') ?? '';\n\n const response = await fetch(targetUrl, {\n method: 'POST',\n headers: {\n ...authHeader,\n ...(contentType && { 'Content-Type': contentType }),\n ...pickIdentityHeaders(request),\n ...pickTraceHeader(request),\n },\n body: request.body,\n duplex: 'half',\n } as RequestInit);\n\n if (!response.ok) {\n return new Response(\n JSON.stringify({ error: 'Failed to upload blob', status: response.status }),\n { status: response.status, headers: { 'Content-Type': 'application/json' } }\n );\n }\n\n const responseText = await response.text();\n return new Response(responseText, {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleBlobUpload exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward blob upload request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n\n async handleToolCompletion(request: Request): Promise<Response> {\n try {\n const body = await request.text();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...authHeader,\n };\n // Forward the runtime's tool-completion correlation headers verbatim\n // (non-hyphenated names, per the runtime OpenAPI). These route the\n // completion to the parked task so the SSE stream resumes.\n const CORRELATION_HEADERS = [\n 'taskid',\n 'parenttaskid',\n 'sessionid',\n 'userid',\n 'assistantid',\n 'agentspaceid',\n 'channelid',\n 'depth',\n ];\n for (const name of CORRELATION_HEADERS) {\n const value = request.headers.get(name);\n if (value) headers[name] = value;\n }\n Object.assign(headers, pickTraceHeader(request));\n\n const response = await fetch(`${baseUrl}/${toolCompletionRoute}`, {\n method: 'POST',\n headers,\n body,\n });\n\n return new Response(await response.text(), {\n status: response.status,\n headers: { 'Content-Type': 'application/json' },\n });\n } catch (error) {\n console.error('AlquimiaProxy handleToolCompletion exception:', error);\n return new Response(\n JSON.stringify({ error: 'Failed to forward tool-completion request' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } }\n );\n }\n },\n };\n}\n"],"mappings":"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","names":[]}
@@ -1,7 +1,7 @@
1
- import { W as WhisperProvider, S as StableDiffusionProvider, C as CharacterizationProvider, R as RatingsProvider, L as LoggerProvider } from '../providers-0Gi78uNQ.mjs';
2
- import { AttachmentPayload, TTSResult } from '../types/index.mjs';
1
+ import { W as WhisperProvider, S as StableDiffusionProvider, C as CharacterizationProvider, R as RatingsProvider, L as LoggerProvider } from '../providers-DiR9cgyo.mjs';
2
+ import { i as AttachmentPayload, T as TTSResult } from '../type-DqX3-9QS.mjs';
3
+ import { T as ToolExecutionResponse } from '../types-CMVbyEv8.mjs';
3
4
  import { AlquimiaAdapter, AlquimiaSDKOptions } from '../adapters/index.mjs';
4
- import { T as ToolExecutionResponse } from '../types-DnfWUE9V.mjs';
5
5
  import '@elastic/apm-rum';
6
6
  import 'ai';
7
7
 
@@ -12,6 +12,7 @@ declare class AlquimiaSDK {
12
12
  private conversationId;
13
13
  private sessionId;
14
14
  private streamId;
15
+ private traceParent;
15
16
  private tools;
16
17
  private extraInstructions;
17
18
  private assistantConfig;
@@ -1,7 +1,7 @@
1
- import { W as WhisperProvider, S as StableDiffusionProvider, C as CharacterizationProvider, R as RatingsProvider, L as LoggerProvider } from '../providers-BJTXCtI3.js';
2
- import { AttachmentPayload, TTSResult } from '../types/index.js';
1
+ import { W as WhisperProvider, S as StableDiffusionProvider, C as CharacterizationProvider, R as RatingsProvider, L as LoggerProvider } from '../providers-b5_yMyMo.js';
2
+ import { i as AttachmentPayload, T as TTSResult } from '../type-xksRnBUW.js';
3
+ import { T as ToolExecutionResponse } from '../types-CMVbyEv8.js';
3
4
  import { AlquimiaAdapter, AlquimiaSDKOptions } from '../adapters/index.js';
4
- import { T as ToolExecutionResponse } from '../types-DnfWUE9V.js';
5
5
  import '@elastic/apm-rum';
6
6
  import 'ai';
7
7
 
@@ -12,6 +12,7 @@ declare class AlquimiaSDK {
12
12
  private conversationId;
13
13
  private sessionId;
14
14
  private streamId;
15
+ private traceParent;
15
16
  private tools;
16
17
  private extraInstructions;
17
18
  private assistantConfig;
package/dist/sdk/index.js CHANGED
@@ -42,6 +42,8 @@ var AlquimiaSDK = class {
42
42
  this.sessionId = null;
43
43
  // Internal subscription id from infer (`taskid` on the wire).
44
44
  this.streamId = null;
45
+ // W3C traceparent for the current turn, so infer and stream share one trace.
46
+ this.traceParent = null;
45
47
  this.tools = [];
46
48
  this.extraInstructions = null;
47
49
  this.assistantConfig = null;
@@ -162,11 +164,12 @@ var AlquimiaSDK = class {
162
164
  const result = (await this.axiosInstance.post(inferUrl, initMessage, {
163
165
  headers: {
164
166
  "Content-Type": "application/json",
165
- "x-trace-parent": traceParent || "",
167
+ ...traceParent && { "x-trace-parent": traceParent },
166
168
  ...adapterHeaders,
167
169
  ...this.buildIdentityHeaders()
168
170
  }
169
171
  })).data;
172
+ this.traceParent = traceParent ?? null;
170
173
  this.streamId = result.taskid ?? null;
171
174
  this.attachmentResponses = result.attachments ?? [];
172
175
  this.attachments = [];
@@ -266,7 +269,10 @@ var AlquimiaSDK = class {
266
269
  if (!this.streamId) {
267
270
  throw new Error("Stream ID not initialized. Call sendMessage() first");
268
271
  }
269
- return this.adapter.resolveStreamUrl(this.streamId);
272
+ const url = this.adapter.resolveStreamUrl(this.streamId);
273
+ if (!this.traceParent) return url;
274
+ const separator = url.includes("?") ? "&" : "?";
275
+ return `${url}${separator}trace_parent=${encodeURIComponent(this.traceParent)}`;
270
276
  }
271
277
  getStreamId() {
272
278
  return this.streamId;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/sdk/index.ts","../../src/sdk/alquimia-sdk.ts"],"sourcesContent":["export { default as AlquimiaSDK } from './alquimia-sdk';","import axios, { AxiosInstance } from 'axios';\nimport {\n StableDiffusionProvider,\n WhisperProvider,\n CharacterizationProvider,\n RatingsProvider,\n LoggerProvider,\n} from '../providers';\nimport { AttachmentPayload, TTSResult, type CommonAttributes } from '../types';\nimport type { AlquimiaAdapter, AlquimiaSDKOptions } from '../adapters';\nimport type { ToolExecutionResponse } from '../genui/types';\n\nclass AlquimiaSDK {\n private adapter: AlquimiaAdapter;\n private assistantId: string;\n private axiosInstance: AxiosInstance;\n private conversationId: string | null = null;\n private sessionId: string | null = null;\n // Internal subscription id from infer (`taskid` on the wire).\n private streamId: string | null = null;\n private tools: any = [];\n private extraInstructions: Record<string, string> | null = null;\n private assistantConfig: any = null;\n private userId: string | null = null;\n private whisperProvider?: WhisperProvider;\n private stableDiffusionProvider?: StableDiffusionProvider;\n private analyzeCharacterizationProvider?: CharacterizationProvider;\n private ratingsProvider?: RatingsProvider;\n private loggerProvider?: LoggerProvider;\n private enforceCharacterization?: boolean;\n private attachments: AttachmentPayload[] = [];\n private attachmentResponses: string[] = [];\n\n constructor(\n assistantId: string,\n adapter: AlquimiaAdapter,\n options: AlquimiaSDKOptions = {}\n ) {\n if (!assistantId) {\n throw new Error('AlquimiaSDK: assistantId is required');\n }\n if (!adapter) {\n throw new Error(\n 'AlquimiaSDK: adapter is required. Use createNextJsAdapter() or createFetchAdapter()'\n );\n }\n\n this.assistantId = assistantId;\n this.adapter = adapter;\n this.enforceCharacterization = options.enforceCharacterization ?? true;\n\n this.axiosInstance = axios.create();\n this.axiosInstance.interceptors.response.use(\n (response) => response,\n async (error) => {\n if (error.response?.status && this.loggerProvider) {\n await this.loggerProvider.logError('Server Error', error, {\n url: error.config.url,\n method: error.config.method,\n data: error.config.data,\n status: error.response.status,\n responseData: error.response.data,\n });\n }\n return Promise.reject(error);\n }\n );\n\n this.textToSpeech = this.textToSpeech.bind(this);\n this.speechToText = this.speechToText.bind(this);\n }\n\n withConversationId(conversationId: string): AlquimiaSDK {\n this.conversationId = conversationId;\n return this;\n }\n\n withAttachments(attachments: AttachmentPayload[]): AlquimiaSDK {\n this.attachments = attachments;\n return this;\n }\n\n withWhisperProvider(provider: WhisperProvider): AlquimiaSDK {\n this.whisperProvider = provider;\n return this;\n }\n\n withStableDiffusionProvider(provider: StableDiffusionProvider): AlquimiaSDK {\n this.stableDiffusionProvider = provider;\n return this;\n }\n\n withAnalyzeCharacterizationProvider(provider: CharacterizationProvider): AlquimiaSDK {\n this.analyzeCharacterizationProvider = provider;\n return this;\n }\n\n withRatingsProvider(provider: RatingsProvider): AlquimiaSDK {\n this.ratingsProvider = provider;\n return this;\n }\n\n withLoggerProvider(provider: LoggerProvider): AlquimiaSDK {\n this.loggerProvider = provider;\n return this;\n }\n\n withTools(tools: any): AlquimiaSDK {\n this.tools = tools;\n return this;\n }\n\n withExtraInstructions(extraInstructions: Record<string, string>): AlquimiaSDK {\n this.extraInstructions = extraInstructions;\n return this;\n }\n\n withAssistantConfig(assistantConfig: any): AlquimiaSDK {\n this.assistantConfig = assistantConfig;\n return this;\n }\n\n withUserId(userId: string): AlquimiaSDK {\n this.userId = userId;\n return this;\n }\n\n getEnforceCharacterization(): boolean {\n return this.enforceCharacterization ?? true;\n }\n\n textToSpeech(text: string): Promise<TTSResult> {\n if (!this.whisperProvider) {\n throw new Error('Whisper provider not initialized');\n }\n return this.whisperProvider.textToSpeech(text);\n }\n\n speechToText(audio: string): Promise<string> {\n if (!this.whisperProvider) {\n throw new Error('Whisper provider not initialized');\n }\n return this.whisperProvider.speechToText(audio);\n }\n\n async sendMessage(query: string, traceParent?: string): Promise<AlquimiaSDK> {\n if (!this.conversationId) {\n throw new Error(\n 'Conversation not initialized. Call withConversationId() before sendMessage()'\n );\n }\n\n const inferUrl = this.adapter.resolveInferUrl(this.assistantId);\n const adapterHeaders = this.adapter.getHeaders?.() ?? {};\n\n const hasClientTools = Array.isArray(this.tools) && this.tools.length > 0;\n\n const initMessage: Record<string, unknown> = {\n query,\n session_id: this.conversationId,\n user_id: this.userId,\n ...(this.extraInstructions && { extra_instructions: this.extraInstructions }),\n ...(this.assistantConfig && { config: this.assistantConfig }),\n ...(hasClientTools && {\n evaluation_strategy: {\n evaluation_strategy_id: 'native',\n tool_schemas: this.tools,\n },\n }),\n };\n\n const result = (\n await this.axiosInstance.post(inferUrl, initMessage, {\n headers: {\n 'Content-Type': 'application/json',\n 'x-trace-parent': traceParent || '',\n ...adapterHeaders,\n ...this.buildIdentityHeaders(),\n },\n })\n ).data as CommonAttributes;\n\n this.streamId = result.taskid ?? null;\n this.attachmentResponses = result.attachments ?? [];\n this.attachments = [];\n\n return this;\n }\n\n /**\n * Complete a pending client-tool execution (the missing \"submit half\" of the\n * client-tool loop). POSTs a {@link ToolExecutionResponse} to the runtime's\n * `/event/tool-completion`. For interactive `render_ui` surfaces `result` is\n * the user's data; for display-only surfaces the SDK sends `{ shown: true }`.\n * The pending call is correlated by `control_id` in the body + the\n * `context-metadata` header (taskid + sessionid).\n */\n async submitToolResult(response: ToolExecutionResponse): Promise<void> {\n const url = this.adapter.resolveToolCompletionUrl?.();\n if (!url) {\n throw new Error(\n 'AlquimiaSDK: adapter does not support tool completion (resolveToolCompletionUrl missing)'\n );\n }\n const adapterHeaders = this.adapter.getHeaders?.() ?? {};\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n assistantid: this.assistantId,\n ...(this.streamId && { taskid: this.streamId }),\n ...(this.conversationId && { sessionid: this.conversationId }),\n ...(this.userId && { userid: this.userId }),\n ...adapterHeaders,\n };\n await this.axiosInstance.post(url, response, { headers });\n }\n\n async generateImage(query: string): Promise<string> {\n if (!this.stableDiffusionProvider) {\n throw new Error('Stable Diffusion provider not initialized');\n }\n return this.stableDiffusionProvider.generateImage(query);\n }\n\n async analyzeCharacterization(text: string): Promise<Record<string, any>> {\n if (!this.analyzeCharacterizationProvider) {\n throw new Error('Analyze characterization provider not initialized');\n }\n return this.analyzeCharacterizationProvider.analyzeCharacterization(text);\n }\n\n async rate(data: any): Promise<Record<string, any>> {\n if (!this.ratingsProvider) {\n throw new Error('Ratings provider not initialized');\n }\n return this.ratingsProvider.rate(data);\n }\n\n async logInfo(message: string, data: any): Promise<void> {\n if (!this.loggerProvider) {\n throw new Error('Logger provider not initialized');\n }\n return this.loggerProvider.logInfo(message, data);\n }\n\n async logError(message: string, error: Error, data: any): Promise<void> {\n if (!this.loggerProvider) {\n throw new Error('Logger provider not initialized');\n }\n return this.loggerProvider.logError(message, error, data);\n }\n\n /**\n * @deprecated The runtime no longer returns attachment IDs from the infer\n * response — attachments are uploaded as standalone blobs and linked to the\n * session via headers. Always returns `[]`; kept for source compatibility.\n */\n getAttachmentResponses(): string[] {\n return this.attachmentResponses;\n }\n\n async uploadAttachment(file: File, _attachmentId?: string): Promise<void> {\n void _attachmentId;\n const url = this.adapter.resolveBlobUploadUrl();\n const adapterHeaders = this.adapter.getHeaders?.() ?? {};\n const formData = new FormData();\n formData.append('file', file);\n await this.axiosInstance.post(url, formData, {\n headers: {\n 'Content-Type': 'multipart/form-data',\n ...adapterHeaders,\n ...this.buildIdentityHeaders(),\n },\n });\n }\n\n /**\n * Identity headers (kebab-case) required by `/context/blob/upload` and\n * the rest of the runtime's internal endpoints introduced in v0.2.0→next.\n */\n private buildIdentityHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'assistant-id': this.assistantId,\n };\n if (this.conversationId) headers['session-id'] = this.conversationId;\n if (this.userId) headers['user-id'] = this.userId;\n if (this.streamId) headers['task-id'] = this.streamId;\n return headers;\n }\n\n getUrlStream(): string {\n if (!this.streamId) {\n throw new Error('Stream ID not initialized. Call sendMessage() first');\n }\n return this.adapter.resolveStreamUrl(this.streamId);\n }\n\n getStreamId(): string | null {\n return this.streamId;\n }\n\n /** Alias for {@link getStreamId} — same value as infer `taskid`. */\n getTaskId(): string | null {\n return this.streamId;\n }\n}\n\nexport default AlquimiaSDK;\n"],"mappings":"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","names":["axios"]}
1
+ {"version":3,"sources":["../../src/sdk/index.ts","../../src/sdk/alquimia-sdk.ts"],"sourcesContent":["export { default as AlquimiaSDK } from './alquimia-sdk';","import axios, { AxiosInstance } from 'axios';\nimport {\n StableDiffusionProvider,\n WhisperProvider,\n CharacterizationProvider,\n RatingsProvider,\n LoggerProvider,\n} from '../providers';\nimport { AttachmentPayload, TTSResult, type CommonAttributes } from '../types';\nimport type { AlquimiaAdapter, AlquimiaSDKOptions } from '../adapters';\nimport type { ToolExecutionResponse } from '../genui/types';\n\nclass AlquimiaSDK {\n private adapter: AlquimiaAdapter;\n private assistantId: string;\n private axiosInstance: AxiosInstance;\n private conversationId: string | null = null;\n private sessionId: string | null = null;\n // Internal subscription id from infer (`taskid` on the wire).\n private streamId: string | null = null;\n // W3C traceparent for the current turn, so infer and stream share one trace.\n private traceParent: string | null = null;\n private tools: any = [];\n private extraInstructions: Record<string, string> | null = null;\n private assistantConfig: any = null;\n private userId: string | null = null;\n private whisperProvider?: WhisperProvider;\n private stableDiffusionProvider?: StableDiffusionProvider;\n private analyzeCharacterizationProvider?: CharacterizationProvider;\n private ratingsProvider?: RatingsProvider;\n private loggerProvider?: LoggerProvider;\n private enforceCharacterization?: boolean;\n private attachments: AttachmentPayload[] = [];\n private attachmentResponses: string[] = [];\n\n constructor(\n assistantId: string,\n adapter: AlquimiaAdapter,\n options: AlquimiaSDKOptions = {}\n ) {\n if (!assistantId) {\n throw new Error('AlquimiaSDK: assistantId is required');\n }\n if (!adapter) {\n throw new Error(\n 'AlquimiaSDK: adapter is required. Use createNextJsAdapter() or createFetchAdapter()'\n );\n }\n\n this.assistantId = assistantId;\n this.adapter = adapter;\n this.enforceCharacterization = options.enforceCharacterization ?? true;\n\n this.axiosInstance = axios.create();\n this.axiosInstance.interceptors.response.use(\n (response) => response,\n async (error) => {\n if (error.response?.status && this.loggerProvider) {\n await this.loggerProvider.logError('Server Error', error, {\n url: error.config.url,\n method: error.config.method,\n data: error.config.data,\n status: error.response.status,\n responseData: error.response.data,\n });\n }\n return Promise.reject(error);\n }\n );\n\n this.textToSpeech = this.textToSpeech.bind(this);\n this.speechToText = this.speechToText.bind(this);\n }\n\n withConversationId(conversationId: string): AlquimiaSDK {\n this.conversationId = conversationId;\n return this;\n }\n\n withAttachments(attachments: AttachmentPayload[]): AlquimiaSDK {\n this.attachments = attachments;\n return this;\n }\n\n withWhisperProvider(provider: WhisperProvider): AlquimiaSDK {\n this.whisperProvider = provider;\n return this;\n }\n\n withStableDiffusionProvider(provider: StableDiffusionProvider): AlquimiaSDK {\n this.stableDiffusionProvider = provider;\n return this;\n }\n\n withAnalyzeCharacterizationProvider(provider: CharacterizationProvider): AlquimiaSDK {\n this.analyzeCharacterizationProvider = provider;\n return this;\n }\n\n withRatingsProvider(provider: RatingsProvider): AlquimiaSDK {\n this.ratingsProvider = provider;\n return this;\n }\n\n withLoggerProvider(provider: LoggerProvider): AlquimiaSDK {\n this.loggerProvider = provider;\n return this;\n }\n\n withTools(tools: any): AlquimiaSDK {\n this.tools = tools;\n return this;\n }\n\n withExtraInstructions(extraInstructions: Record<string, string>): AlquimiaSDK {\n this.extraInstructions = extraInstructions;\n return this;\n }\n\n withAssistantConfig(assistantConfig: any): AlquimiaSDK {\n this.assistantConfig = assistantConfig;\n return this;\n }\n\n withUserId(userId: string): AlquimiaSDK {\n this.userId = userId;\n return this;\n }\n\n getEnforceCharacterization(): boolean {\n return this.enforceCharacterization ?? true;\n }\n\n textToSpeech(text: string): Promise<TTSResult> {\n if (!this.whisperProvider) {\n throw new Error('Whisper provider not initialized');\n }\n return this.whisperProvider.textToSpeech(text);\n }\n\n speechToText(audio: string): Promise<string> {\n if (!this.whisperProvider) {\n throw new Error('Whisper provider not initialized');\n }\n return this.whisperProvider.speechToText(audio);\n }\n\n async sendMessage(query: string, traceParent?: string): Promise<AlquimiaSDK> {\n if (!this.conversationId) {\n throw new Error(\n 'Conversation not initialized. Call withConversationId() before sendMessage()'\n );\n }\n\n const inferUrl = this.adapter.resolveInferUrl(this.assistantId);\n const adapterHeaders = this.adapter.getHeaders?.() ?? {};\n\n const hasClientTools = Array.isArray(this.tools) && this.tools.length > 0;\n\n const initMessage: Record<string, unknown> = {\n query,\n session_id: this.conversationId,\n user_id: this.userId,\n ...(this.extraInstructions && { extra_instructions: this.extraInstructions }),\n ...(this.assistantConfig && { config: this.assistantConfig }),\n ...(hasClientTools && {\n evaluation_strategy: {\n evaluation_strategy_id: 'native',\n tool_schemas: this.tools,\n },\n }),\n };\n\n const result = (\n await this.axiosInstance.post(inferUrl, initMessage, {\n headers: {\n 'Content-Type': 'application/json',\n ...(traceParent && { 'x-trace-parent': traceParent }),\n ...adapterHeaders,\n ...this.buildIdentityHeaders(),\n },\n })\n ).data as CommonAttributes;\n\n this.traceParent = traceParent ?? null;\n this.streamId = result.taskid ?? null;\n this.attachmentResponses = result.attachments ?? [];\n this.attachments = [];\n\n return this;\n }\n\n /**\n * Complete a pending client-tool execution (the missing \"submit half\" of the\n * client-tool loop). POSTs a {@link ToolExecutionResponse} to the runtime's\n * `/event/tool-completion`. For interactive `render_ui` surfaces `result` is\n * the user's data; for display-only surfaces the SDK sends `{ shown: true }`.\n * The pending call is correlated by `control_id` in the body + the\n * `context-metadata` header (taskid + sessionid).\n */\n async submitToolResult(response: ToolExecutionResponse): Promise<void> {\n const url = this.adapter.resolveToolCompletionUrl?.();\n if (!url) {\n throw new Error(\n 'AlquimiaSDK: adapter does not support tool completion (resolveToolCompletionUrl missing)'\n );\n }\n const adapterHeaders = this.adapter.getHeaders?.() ?? {};\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n assistantid: this.assistantId,\n ...(this.streamId && { taskid: this.streamId }),\n ...(this.conversationId && { sessionid: this.conversationId }),\n ...(this.userId && { userid: this.userId }),\n ...adapterHeaders,\n };\n await this.axiosInstance.post(url, response, { headers });\n }\n\n async generateImage(query: string): Promise<string> {\n if (!this.stableDiffusionProvider) {\n throw new Error('Stable Diffusion provider not initialized');\n }\n return this.stableDiffusionProvider.generateImage(query);\n }\n\n async analyzeCharacterization(text: string): Promise<Record<string, any>> {\n if (!this.analyzeCharacterizationProvider) {\n throw new Error('Analyze characterization provider not initialized');\n }\n return this.analyzeCharacterizationProvider.analyzeCharacterization(text);\n }\n\n async rate(data: any): Promise<Record<string, any>> {\n if (!this.ratingsProvider) {\n throw new Error('Ratings provider not initialized');\n }\n return this.ratingsProvider.rate(data);\n }\n\n async logInfo(message: string, data: any): Promise<void> {\n if (!this.loggerProvider) {\n throw new Error('Logger provider not initialized');\n }\n return this.loggerProvider.logInfo(message, data);\n }\n\n async logError(message: string, error: Error, data: any): Promise<void> {\n if (!this.loggerProvider) {\n throw new Error('Logger provider not initialized');\n }\n return this.loggerProvider.logError(message, error, data);\n }\n\n /**\n * @deprecated The runtime no longer returns attachment IDs from the infer\n * response — attachments are uploaded as standalone blobs and linked to the\n * session via headers. Always returns `[]`; kept for source compatibility.\n */\n getAttachmentResponses(): string[] {\n return this.attachmentResponses;\n }\n\n async uploadAttachment(file: File, _attachmentId?: string): Promise<void> {\n void _attachmentId;\n const url = this.adapter.resolveBlobUploadUrl();\n const adapterHeaders = this.adapter.getHeaders?.() ?? {};\n const formData = new FormData();\n formData.append('file', file);\n await this.axiosInstance.post(url, formData, {\n headers: {\n 'Content-Type': 'multipart/form-data',\n ...adapterHeaders,\n ...this.buildIdentityHeaders(),\n },\n });\n }\n\n /**\n * Identity headers (kebab-case) required by `/context/blob/upload` and\n * the rest of the runtime's internal endpoints introduced in v0.2.0→next.\n */\n private buildIdentityHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'assistant-id': this.assistantId,\n };\n if (this.conversationId) headers['session-id'] = this.conversationId;\n if (this.userId) headers['user-id'] = this.userId;\n if (this.streamId) headers['task-id'] = this.streamId;\n return headers;\n }\n\n getUrlStream(): string {\n if (!this.streamId) {\n throw new Error('Stream ID not initialized. Call sendMessage() first');\n }\n\n const url = this.adapter.resolveStreamUrl(this.streamId);\n if (!this.traceParent) return url;\n\n // `EventSource` cannot set request headers, so the turn's traceparent rides\n // the URL. The proxy turns it back into `x-trace-parent` and does not pass\n // the param upstream; without this the stream leg — where the whole\n // inference actually happens — lands in a different trace than the infer.\n const separator = url.includes('?') ? '&' : '?';\n return `${url}${separator}trace_parent=${encodeURIComponent(this.traceParent)}`;\n }\n\n getStreamId(): string | null {\n return this.streamId;\n }\n\n /** Alias for {@link getStreamId} — same value as infer `taskid`. */\n getTaskId(): string | null {\n return this.streamId;\n }\n}\n\nexport default AlquimiaSDK;\n"],"mappings":"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","names":["axios"]}
@@ -6,6 +6,8 @@ var AlquimiaSDK = class {
6
6
  this.sessionId = null;
7
7
  // Internal subscription id from infer (`taskid` on the wire).
8
8
  this.streamId = null;
9
+ // W3C traceparent for the current turn, so infer and stream share one trace.
10
+ this.traceParent = null;
9
11
  this.tools = [];
10
12
  this.extraInstructions = null;
11
13
  this.assistantConfig = null;
@@ -126,11 +128,12 @@ var AlquimiaSDK = class {
126
128
  const result = (await this.axiosInstance.post(inferUrl, initMessage, {
127
129
  headers: {
128
130
  "Content-Type": "application/json",
129
- "x-trace-parent": traceParent || "",
131
+ ...traceParent && { "x-trace-parent": traceParent },
130
132
  ...adapterHeaders,
131
133
  ...this.buildIdentityHeaders()
132
134
  }
133
135
  })).data;
136
+ this.traceParent = traceParent ?? null;
134
137
  this.streamId = result.taskid ?? null;
135
138
  this.attachmentResponses = result.attachments ?? [];
136
139
  this.attachments = [];
@@ -230,7 +233,10 @@ var AlquimiaSDK = class {
230
233
  if (!this.streamId) {
231
234
  throw new Error("Stream ID not initialized. Call sendMessage() first");
232
235
  }
233
- return this.adapter.resolveStreamUrl(this.streamId);
236
+ const url = this.adapter.resolveStreamUrl(this.streamId);
237
+ if (!this.traceParent) return url;
238
+ const separator = url.includes("?") ? "&" : "?";
239
+ return `${url}${separator}trace_parent=${encodeURIComponent(this.traceParent)}`;
234
240
  }
235
241
  getStreamId() {
236
242
  return this.streamId;