@qelos/sdk 3.11.2 → 3.11.4

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 (51) hide show
  1. package/dist/administrator/admin-lambdas.d.ts +12 -0
  2. package/dist/administrator/admin-lambdas.js +33 -0
  3. package/dist/administrator/admin-lambdas.js.map +1 -0
  4. package/dist/administrator/index.d.ts +4 -0
  5. package/dist/administrator/index.js +6 -0
  6. package/dist/administrator/index.js.map +1 -1
  7. package/dist/administrator/integrations.d.ts +35 -0
  8. package/dist/administrator/integrations.js +33 -0
  9. package/dist/administrator/integrations.js.map +1 -0
  10. package/dist/ai/chat.d.ts +29 -0
  11. package/dist/ai/chat.js +146 -0
  12. package/dist/ai/chat.js.map +1 -0
  13. package/dist/ai/index.d.ts +4 -0
  14. package/dist/ai/index.js +5 -0
  15. package/dist/ai/index.js.map +1 -0
  16. package/dist/ai/rag.d.ts +33 -0
  17. package/dist/ai/rag.js +38 -0
  18. package/dist/ai/rag.js.map +1 -0
  19. package/dist/ai/threads.d.ts +33 -0
  20. package/dist/ai/threads.js +39 -0
  21. package/dist/ai/threads.js.map +1 -0
  22. package/dist/ai/types.d.ts +91 -0
  23. package/dist/ai/types.js +2 -0
  24. package/dist/ai/types.js.map +1 -0
  25. package/dist/ai.d.ts +102 -0
  26. package/dist/ai.js +115 -0
  27. package/dist/ai.js.map +1 -0
  28. package/dist/blueprints.d.ts +7 -0
  29. package/dist/blueprints.js +4 -0
  30. package/dist/blueprints.js.map +1 -1
  31. package/dist/index.d.ts +4 -0
  32. package/dist/index.js +6 -0
  33. package/dist/index.js.map +1 -1
  34. package/dist/lambdas.d.ts +12 -0
  35. package/dist/lambdas.js +36 -0
  36. package/dist/lambdas.js.map +1 -0
  37. package/examples/ai-sdk-usage.ts +170 -0
  38. package/package.json +1 -1
  39. package/src/administrator/admin-lambdas.ts +38 -0
  40. package/src/administrator/index.ts +7 -1
  41. package/src/administrator/integrations.ts +65 -0
  42. package/src/ai/chat.ts +187 -0
  43. package/src/ai/index.ts +4 -0
  44. package/src/ai/rag.ts +72 -0
  45. package/src/ai/threads.ts +56 -0
  46. package/src/ai/types.ts +101 -0
  47. package/src/ai-sdk-migration-guide.md +172 -0
  48. package/src/ai.ts +179 -0
  49. package/src/blueprints.ts +5 -0
  50. package/src/index.ts +7 -2
  51. package/src/lambdas.ts +41 -0
@@ -0,0 +1,65 @@
1
+ import { QelosSDKOptions, RequestExtra } from '../types';
2
+ import BaseSDK from '../base-sdk';
3
+ import { IIntegration } from '@qelos/global-types';
4
+
5
+ export default class QlIntegrations extends BaseSDK {
6
+ private relativePath = '/api/integrations';
7
+
8
+ constructor(private options: QelosSDKOptions) {
9
+ super(options)
10
+ }
11
+
12
+ getIntegration(integrationId: string, extra?: RequestExtra) {
13
+ return this.callJsonApi<IIntegration>(`${this.relativePath}/${integrationId}`, extra);
14
+ }
15
+
16
+ getList(query?: {
17
+ plugin?: string;
18
+ user?: string;
19
+ 'trigger.source'?: string;
20
+ 'target.source'?: string;
21
+ 'trigger.kind'?: string;
22
+ 'target.kind'?: string;
23
+ kind?: string;
24
+ source?: string;
25
+ active?: boolean;
26
+ id?: string;
27
+ _id?: string;
28
+ }, extra?: RequestExtra) {
29
+ return this.callJsonApi<IIntegration[]>(this.relativePath + this.getQueryParams(query), extra);
30
+ }
31
+
32
+ remove(integrationId: string): Promise<any> {
33
+ return this.callApi(`${this.relativePath}/${integrationId}`, { method: 'delete' });
34
+ }
35
+
36
+ update(integrationId: string, changes: {
37
+ active?: boolean;
38
+ trigger?: any;
39
+ target?: any;
40
+ dataManipulation?: any;
41
+ }): Promise<IIntegration> {
42
+ return this.callJsonApi<IIntegration>(
43
+ `${this.relativePath}/${integrationId}`,
44
+ {
45
+ method: 'put',
46
+ headers: { 'content-type': 'application/json' },
47
+ body: JSON.stringify(changes)
48
+ }
49
+ )
50
+ }
51
+
52
+ create(integration: {
53
+ trigger: any;
54
+ target: any;
55
+ dataManipulation?: any;
56
+ active?: boolean;
57
+ }): Promise<IIntegration> {
58
+ return this.callJsonApi<IIntegration>(this.relativePath, {
59
+ method: 'post',
60
+ headers: { 'content-type': 'application/json' },
61
+ body: JSON.stringify(integration)
62
+ })
63
+ }
64
+
65
+ }
package/src/ai/chat.ts ADDED
@@ -0,0 +1,187 @@
1
+ import BaseSDK from '../base-sdk';
2
+ import { QelosSDKOptions } from '../types';
3
+ import {
4
+ IChatCompletionOptions,
5
+ IChatCompletionResponse,
6
+ ISSEStreamProcessor
7
+ } from '../ai';
8
+
9
+ export default class ChatSDK extends BaseSDK {
10
+ private relativePath = '/api/ai';
11
+
12
+ constructor(options: QelosSDKOptions) {
13
+ super(options);
14
+ }
15
+
16
+ /**
17
+ * Create a chat completion without a thread
18
+ */
19
+ chat(
20
+ integrationId: string,
21
+ options: IChatCompletionOptions
22
+ ): Promise<IChatCompletionResponse> {
23
+ const queryParams = this.getQueryParams(options.queryParams || {});
24
+ return this.callJsonApi<IChatCompletionResponse>(`${this.relativePath}/${integrationId}/chat-completion${queryParams}`, {
25
+ method: 'POST',
26
+ headers: { 'content-type': 'application/json' },
27
+ body: JSON.stringify(options)
28
+ });
29
+ }
30
+
31
+ /**
32
+ * Create a chat completion with a thread
33
+ */
34
+ chatInThread(
35
+ integrationId: string,
36
+ threadId: string,
37
+ options: IChatCompletionOptions
38
+ ): Promise<IChatCompletionResponse> {
39
+ const queryParams = this.getQueryParams(options.queryParams || {});
40
+ return this.callJsonApi<IChatCompletionResponse>(
41
+ `${this.relativePath}/${integrationId}/chat-completion/${threadId}${queryParams}`,
42
+ {
43
+ method: 'POST',
44
+ headers: { 'content-type': 'application/json' },
45
+ body: JSON.stringify(options)
46
+ }
47
+ );
48
+ }
49
+
50
+ /**
51
+ * Create a streaming chat completion without a thread
52
+ * Returns a ReadableStream for Server-Sent Events
53
+ */
54
+ async stream(
55
+ integrationId: string,
56
+ options: IChatCompletionOptions
57
+ ): Promise<ReadableStream<Uint8Array>> {
58
+ const queryParams = this.getQueryParams({ ...options.queryParams, stream: true });
59
+ const response = await this.callApi(`${this.relativePath}/${integrationId}/chat-completion${queryParams}`, {
60
+ method: 'POST',
61
+ headers: {
62
+ 'content-type': 'application/json',
63
+ 'accept': 'text/event-stream'
64
+ },
65
+ body: JSON.stringify({ ...options, stream: true })
66
+ });
67
+
68
+ if (!response.ok) {
69
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
70
+ }
71
+
72
+ return response.body!;
73
+ }
74
+
75
+ /**
76
+ * Create a streaming chat completion with a thread
77
+ * Returns a ReadableStream for Server-Sent Events
78
+ */
79
+ async streamInThread(
80
+ integrationId: string,
81
+ threadId: string,
82
+ options: IChatCompletionOptions
83
+ ): Promise<ReadableStream<Uint8Array>> {
84
+ const queryParams = this.getQueryParams({ ...options.queryParams, stream: true });
85
+ const response = await this.callApi(
86
+ `${this.relativePath}/${integrationId}/chat-completion/${threadId}${queryParams}`,
87
+ {
88
+ method: 'POST',
89
+ headers: {
90
+ 'content-type': 'application/json',
91
+ 'accept': 'text/event-stream'
92
+ },
93
+ body: JSON.stringify({ ...options, stream: true })
94
+ }
95
+ );
96
+
97
+ if (!response.ok) {
98
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
99
+ }
100
+
101
+ return response.body!;
102
+ }
103
+
104
+ /**
105
+ * Helper method to parse Server-Sent Events stream
106
+ */
107
+ parseSSEStream(stream: ReadableStream<Uint8Array>): ISSEStreamProcessor {
108
+ const processStream = async (onData: (data: any) => void | boolean): Promise<void> => {
109
+ const reader = stream.getReader();
110
+ const decoder = new TextDecoder();
111
+ let buffer = "";
112
+
113
+ try {
114
+ while (true) {
115
+ const { done, value } = await reader.read();
116
+ if (done) break;
117
+
118
+ buffer += decoder.decode(value, { stream: true });
119
+ let lines = buffer.split(/\r?\n/);
120
+ buffer = lines.pop() || ""; // Keep incomplete line
121
+
122
+ for (const line of lines) {
123
+ if (line.startsWith('data: ')) {
124
+ const data = line.slice(6);
125
+ if (data === '[DONE]') return;
126
+
127
+ try {
128
+ const parsed = JSON.parse(data);
129
+ const shouldContinue = onData(parsed);
130
+ if (shouldContinue === false) {
131
+ return;
132
+ }
133
+ } catch (e) {
134
+ // Skip invalid JSON
135
+ }
136
+ }
137
+ }
138
+ }
139
+ } finally {
140
+ reader.releaseLock();
141
+ }
142
+ };
143
+
144
+ const processor = {
145
+ async *[Symbol.asyncIterator]() {
146
+ const reader = stream.getReader();
147
+ const decoder = new TextDecoder();
148
+ let buffer = "";
149
+
150
+ try {
151
+ while (true) {
152
+ const { done, value } = await reader.read();
153
+ if (done) {
154
+ break;
155
+ }
156
+
157
+ buffer += decoder.decode(value, { stream: true });
158
+ let lines = buffer.split(/\r?\n/);
159
+ buffer = lines.pop() || ""; // Keep incomplete line
160
+
161
+ for (const line of lines) {
162
+ if (line.startsWith('data: ')) {
163
+ const data = line.slice(6);
164
+ if (data === '[DONE]') {
165
+ return;
166
+ }
167
+
168
+ try {
169
+ const parsed = JSON.parse(data);
170
+ yield parsed;
171
+ } catch (e) {
172
+ //
173
+ }
174
+ }
175
+ }
176
+ }
177
+ } finally {
178
+ reader.releaseLock();
179
+ }
180
+ },
181
+
182
+ processManually: processStream
183
+ };
184
+
185
+ return processor as ISSEStreamProcessor;
186
+ }
187
+ }
@@ -0,0 +1,4 @@
1
+ export { default as ThreadsSDK } from './threads';
2
+ export { default as ChatSDK } from './chat';
3
+ export { default as RAGSDK } from './rag';
4
+ export * from './types';
package/src/ai/rag.ts ADDED
@@ -0,0 +1,72 @@
1
+ import BaseSDK from '../base-sdk';
2
+ import { QelosSDKOptions } from '../types';
3
+ import {
4
+ ICreateVectorStorageRequest,
5
+ IUploadContentRequest,
6
+ IClearStorageRequest,
7
+ IVectorStore
8
+ } from '../ai';
9
+
10
+ export default class RAGSDK extends BaseSDK {
11
+ private relativePath = '/api/ai';
12
+
13
+ constructor(options: QelosSDKOptions) {
14
+ super(options);
15
+ }
16
+
17
+ /**
18
+ * Create a vector storage for RAG
19
+ */
20
+ createStorage(
21
+ sourceId: string,
22
+ data: ICreateVectorStorageRequest
23
+ ): Promise<{
24
+ success: boolean;
25
+ message: string;
26
+ vectorStore: IVectorStore;
27
+ }> {
28
+ return this.callJsonApi<any>(`${this.relativePath}/sources/${sourceId}/storage${this.getQueryParams({})}`, {
29
+ method: 'POST',
30
+ headers: { 'content-type': 'application/json' },
31
+ body: JSON.stringify(data)
32
+ });
33
+ }
34
+
35
+ /**
36
+ * Upload content to vector storage
37
+ */
38
+ uploadContent(
39
+ sourceId: string,
40
+ data: IUploadContentRequest
41
+ ): Promise<{
42
+ success: boolean;
43
+ message: string;
44
+ fileId: string;
45
+ vectorStoreId: string;
46
+ }> {
47
+ return this.callJsonApi<any>(`${this.relativePath}/sources/${sourceId}/storage/upload${this.getQueryParams({})}`, {
48
+ method: 'POST',
49
+ headers: { 'content-type': 'application/json' },
50
+ body: JSON.stringify(data)
51
+ });
52
+ }
53
+
54
+ /**
55
+ * Clear files from vector storage
56
+ */
57
+ clearStorage(
58
+ sourceId: string,
59
+ data: IClearStorageRequest
60
+ ): Promise<{
61
+ success: boolean;
62
+ message: string;
63
+ clearedCount: number;
64
+ vectorStoreId: string;
65
+ }> {
66
+ return this.callJsonApi<any>(`${this.relativePath}/sources/${sourceId}/storage/clear${this.getQueryParams({})}`, {
67
+ method: 'POST',
68
+ headers: { 'content-type': 'application/json' },
69
+ body: JSON.stringify(data)
70
+ });
71
+ }
72
+ }
@@ -0,0 +1,56 @@
1
+ import BaseSDK from '../base-sdk';
2
+ import { QelosSDKOptions } from '../types';
3
+ import { IThread, ICreateThreadRequest } from '../ai';
4
+
5
+ export default class ThreadsSDK extends BaseSDK {
6
+ private relativePath = '/api/ai';
7
+
8
+ constructor(options: QelosSDKOptions) {
9
+ super(options);
10
+ }
11
+
12
+ /**
13
+ * Create a new thread
14
+ */
15
+ create(data: ICreateThreadRequest): Promise<IThread> {
16
+ return this.callJsonApi<IThread>(this.relativePath + '/threads', {
17
+ method: 'POST',
18
+ headers: { 'content-type': 'application/json' },
19
+ body: JSON.stringify(data)
20
+ });
21
+ }
22
+
23
+ /**
24
+ * Get a specific thread by ID
25
+ */
26
+ getOne(threadId: string): Promise<IThread> {
27
+ return this.callJsonApi<IThread>(`${this.relativePath}/threads/${threadId}${this.getQueryParams({})}`);
28
+ }
29
+
30
+ /**
31
+ * List threads with optional filters
32
+ */
33
+ list(options?: {
34
+ integration?: string;
35
+ limit?: number;
36
+ page?: number;
37
+ sort?: string;
38
+ user?: string;
39
+ workspace?: string;
40
+ [key: string]: string | number;
41
+ }): Promise<IThread[]> {
42
+ const queryParams = this.getQueryParams(options);
43
+ return this.callJsonApi<IThread[]>(
44
+ `${this.relativePath}/threads${queryParams}`
45
+ );
46
+ }
47
+
48
+ /**
49
+ * Delete a thread
50
+ */
51
+ delete(threadId: string): Promise<{ success: boolean }> {
52
+ return this.callJsonApi<{ success: boolean }>(`${this.relativePath}/threads/${threadId}${this.getQueryParams({})}`, {
53
+ method: 'DELETE'
54
+ });
55
+ }
56
+ }
@@ -0,0 +1,101 @@
1
+ export interface IMessage {
2
+ role: string;
3
+ content: string;
4
+ timestamp?: Date | string;
5
+ tool_calls?: any[];
6
+ name?: string;
7
+ tool_call_id?: string;
8
+ function_call?: any;
9
+ message_id?: string;
10
+ }
11
+
12
+ export interface IMessageSummary {
13
+ fromIndex: number;
14
+ toIndex: number;
15
+ summary: string;
16
+ }
17
+
18
+ export interface IThread {
19
+ _id?: string;
20
+ integration: string;
21
+ title?: string;
22
+ messages: IMessage[];
23
+ messageSummaries: IMessageSummary[];
24
+ created?: Date;
25
+ updated?: Date;
26
+ user?: string;
27
+ workspace?: string;
28
+ }
29
+
30
+ export interface IChatCompletionOptions {
31
+ messages: IMessage[];
32
+ model?: string;
33
+ temperature?: number;
34
+ top_p?: number;
35
+ frequency_penalty?: number;
36
+ presence_penalty?: number;
37
+ stop?: string | string[];
38
+ max_tokens?: number;
39
+ response_format?: any;
40
+ context?: Record<string, any>;
41
+ stream?: boolean;
42
+ queryParams?: Record<string, any>;
43
+ }
44
+
45
+ export interface ISSEStreamProcessor extends AsyncIterable<any> {
46
+ processManually(onData: (data: any) => void | boolean): Promise<void>;
47
+ }
48
+
49
+ export interface IChatCompletionResponse {
50
+ id: string;
51
+ object: string;
52
+ created: number;
53
+ model: string;
54
+ choices: Array<{
55
+ index: number;
56
+ message: IMessage;
57
+ finish_reason: string;
58
+ }>;
59
+ usage?: {
60
+ prompt_tokens: number;
61
+ completion_tokens: number;
62
+ total_tokens: number;
63
+ };
64
+ }
65
+
66
+ export interface ICreateThreadRequest {
67
+ integration: string;
68
+ title?: string;
69
+ }
70
+
71
+ export interface ICreateVectorStorageRequest {
72
+ integrationId: string;
73
+ scope: 'thread' | 'user' | 'workspace' | 'tenant';
74
+ subjectId?: string;
75
+ expirationAfterDays?: number;
76
+ }
77
+
78
+ export interface IUploadContentRequest {
79
+ integrationId?: string;
80
+ vectorStoreId?: string;
81
+ content: string | object;
82
+ fileName?: string;
83
+ metadata?: Record<string, any>;
84
+ }
85
+
86
+ export interface IClearStorageRequest {
87
+ integrationId?: string;
88
+ vectorStoreId?: string;
89
+ fileIds?: string[];
90
+ }
91
+
92
+ export interface IVectorStore {
93
+ _id: string;
94
+ scope: string;
95
+ subjectId?: string;
96
+ tenant: string;
97
+ agent: string;
98
+ externalId: string;
99
+ expirationAfterDays?: number;
100
+ created: Date;
101
+ }
@@ -0,0 +1,172 @@
1
+ # Qelos AI SDK Migration Guide
2
+
3
+ The Qelos AI SDK has been refactored to provide a more organized and intuitive API with three sub-SDKs:
4
+ - `threads` - Thread CRUD operations
5
+ - `chat` - Chat completion (streaming and non-streaming) and SSE parsing
6
+ - `rag` - Vector storage management for RAG (Retrieval-Augmented Generation)
7
+
8
+ ## File Structure
9
+
10
+ The SDK is now split into multiple files for better organization:
11
+ ```
12
+ /packages/sdk/src/ai/
13
+ ├── index.ts - Exports all sub-SDKs and types
14
+ ├── types.ts - All AI-related type definitions
15
+ ├── threads.ts - ThreadsSDK implementation
16
+ ├── chat.ts - ChatSDK implementation
17
+ └── rag.ts - RAGSDK implementation
18
+ ```
19
+
20
+ ## New API Structure
21
+
22
+ ### 1. Threads Sub-SDK
23
+
24
+ All thread-related operations are now available under `sdk.ai.threads`:
25
+
26
+ ```typescript
27
+ // Create a new thread
28
+ const thread = await sdk.ai.threads.create({
29
+ integration: 'integration-id',
30
+ title: 'Optional title'
31
+ });
32
+
33
+ // Get a specific thread
34
+ const thread = await sdk.ai.threads.getOne('thread-id');
35
+
36
+ // List threads with filters
37
+ const threads = await sdk.ai.threads.list({
38
+ integration: 'integration-id',
39
+ limit: 10,
40
+ page: 1
41
+ });
42
+
43
+ // Delete a thread
44
+ await sdk.ai.threads.delete('thread-id');
45
+ ```
46
+
47
+ ### 2. Chat Sub-SDK
48
+
49
+ All chat completion operations are now available under `sdk.ai.chat`:
50
+
51
+ ```typescript
52
+ // Non-streaming chat
53
+ const response = await sdk.ai.chat.chat('integration-id', {
54
+ messages: [{ role: 'user', content: 'Hello!' }],
55
+ model: 'gpt-4',
56
+ queryParams: { bypassAdmin: true } // Optional query parameters
57
+ });
58
+
59
+ // Non-streaming chat in thread
60
+ const response = await sdk.ai.chat.chatInThread('integration-id', 'thread-id', {
61
+ messages: [{ role: 'user', content: 'Hello!' }]
62
+ });
63
+
64
+ // Streaming chat
65
+ const stream = await sdk.ai.chat.stream('integration-id', {
66
+ messages: [{ role: 'user', content: 'Hello!' }],
67
+ stream: true
68
+ });
69
+
70
+ // Streaming chat in thread
71
+ const stream = await sdk.ai.chat.streamInThread('integration-id', 'thread-id', {
72
+ messages: [{ role: 'user', content: 'Hello!' }],
73
+ stream: true
74
+ });
75
+
76
+ // Parse SSE stream
77
+ const processor = sdk.ai.chat.parseSSEStream(stream);
78
+ for await (const chunk of processor) {
79
+ console.log(chunk);
80
+ }
81
+ ```
82
+
83
+ ### 3. RAG Sub-SDK
84
+
85
+ All vector storage operations are now available under `sdk.ai.rag`:
86
+
87
+ ```typescript
88
+ // Create vector storage
89
+ const result = await sdk.ai.rag.createStorage('source-id', {
90
+ integrationId: 'integration-id',
91
+ scope: 'thread', // 'thread' | 'user' | 'workspace' | 'tenant'
92
+ subjectId: 'thread-id', // Required for non-tenant scopes
93
+ expirationAfterDays: 30
94
+ });
95
+
96
+ // Upload content to storage
97
+ const uploadResult = await sdk.ai.rag.uploadContent('source-id', {
98
+ integrationId: 'integration-id',
99
+ content: 'Your content here', // Can be string or object
100
+ fileName: 'document.txt',
101
+ metadata: { type: 'documentation' }
102
+ });
103
+
104
+ // Clear files from storage
105
+ const clearResult = await sdk.ai.rag.clearStorage('source-id', {
106
+ integrationId: 'integration-id',
107
+ fileIds: ['file-id-1', 'file-id-2'] // Optional: clears all if not provided
108
+ });
109
+
110
+ // Get vector stores (internal API)
111
+ const stores = await sdk.ai.rag.getVectorStores({
112
+ scope: 'thread',
113
+ subjectId: 'thread-id'
114
+ });
115
+
116
+ // Internal API methods (for server-side use)
117
+ await sdk.ai.rag.uploadContentInternal('source-id', data);
118
+ await sdk.ai.rag.clearStorageInternal('source-id', data);
119
+ ```
120
+
121
+ ## Backward Compatibility
122
+
123
+ The old API methods are still available and marked as deprecated. They internally delegate to the new sub-SDKs:
124
+
125
+ ```typescript
126
+ // These still work but are deprecated:
127
+ await sdk.ai.createThread(data); // → sdk.ai.threads.create(data)
128
+ await sdk.ai.getThread(id); // → sdk.ai.threads.getOne(id)
129
+ await sdk.ai.streamChat(id, options); // → sdk.ai.chat.stream(id, options)
130
+ await sdk.ai.parseSSEStream(stream); // → sdk.ai.chat.parseSSEStream(stream)
131
+ ```
132
+
133
+ ## Migration Benefits
134
+
135
+ 1. **Better Organization**: Related functionality is grouped together
136
+ 2. **Improved Discoverability**: IDE autocomplete shows relevant methods for each sub-SDK
137
+ 3. **Type Safety**: Better TypeScript support with specific interfaces for each sub-domain
138
+ 4. **Future-Proof**: Easy to extend each sub-SDK independently
139
+
140
+ ## Updating Your Code
141
+
142
+ While the old API still works, we recommend updating to the new structure:
143
+
144
+ ```typescript
145
+ // Old way
146
+ const thread = await sdk.ai.createThread({ integration: 'id' });
147
+ const stream = await sdk.ai.streamChat('id', options);
148
+ for await (const chunk of sdk.ai.parseSSEStream(stream)) {
149
+ // process chunk
150
+ }
151
+
152
+ // New way
153
+ const thread = await sdk.ai.threads.create({ integration: 'id' });
154
+ const stream = await sdk.ai.chat.stream('id', options);
155
+ for await (const chunk of sdk.ai.chat.parseSSEStream(stream)) {
156
+ // process chunk
157
+ }
158
+ ```
159
+
160
+ ## Query Parameters
161
+
162
+ The `IChatCompletionOptions` interface now includes an optional `queryParams` field for passing additional query parameters:
163
+
164
+ ```typescript
165
+ await sdk.ai.chat.stream('integration-id', {
166
+ messages: [{ role: 'user', content: 'Hello!' }],
167
+ queryParams: {
168
+ bypassAdmin: true,
169
+ customParam: 'value'
170
+ }
171
+ });
172
+ ```