@hasura/promptql 1.0.0 → 2.0.0-alpha.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.
Files changed (45) hide show
  1. package/.turbo/turbo-build.log +16 -0
  2. package/README.md +314 -135
  3. package/biome.json +8 -0
  4. package/dist/index.d.mts +4404 -0
  5. package/dist/index.d.ts +4404 -5
  6. package/dist/index.js +1 -1
  7. package/dist/index.mjs +1 -925
  8. package/package.json +44 -53
  9. package/src/auth/auth.test.ts +24 -0
  10. package/src/auth/auth.ts +130 -0
  11. package/src/auth/index.ts +2 -0
  12. package/src/auth/types.ts +56 -0
  13. package/src/generated/ChatV2ServerSchema.json +5841 -0
  14. package/src/generated/ChatV2ServerTypes.ts +2747 -0
  15. package/src/generated/ThreadEvents.example.json +1645 -0
  16. package/src/generated/graphql.ts +12121 -0
  17. package/src/graphql/README.md +70 -0
  18. package/src/graphql/mutations/sendThreadMessage.gql +16 -0
  19. package/src/graphql/mutations/startThread.gql +19 -0
  20. package/src/graphql/queries/getProjectInfo.gql +7 -0
  21. package/src/graphql/queries/thread.gql +39 -0
  22. package/src/graphql/subscriptions/subscribeThreadEventsByThreadId.gql +7 -0
  23. package/src/index.ts +13 -0
  24. package/src/sdk/apollo.ts +63 -0
  25. package/src/sdk/client.ts +273 -0
  26. package/src/sdk/index.ts +4 -0
  27. package/src/sdk/types.ts +254 -0
  28. package/src/sdk/utils.ts +684 -0
  29. package/src/utils.ts +16 -0
  30. package/tsconfig.json +8 -0
  31. package/LICENSE +0 -201
  32. package/dist/index.iife.js +0 -1
  33. package/dist/index.umd.js +0 -1
  34. package/dist/promptql.d.ts +0 -598
  35. package/dist/types.d.ts +0 -26
  36. package/dist/utils/index.d.ts +0 -2
  37. package/dist/utils/query-chunks.d.ts +0 -35
  38. package/dist/utils/query-stream.d.ts +0 -3
  39. package/dist/utils/utils.d.ts +0 -36
  40. package/dist/v1/client.d.ts +0 -8
  41. package/dist/v1/index.d.ts +0 -11
  42. package/dist/v1/types.d.ts +0 -100
  43. package/dist/v2/client.d.ts +0 -8
  44. package/dist/v2/index.d.ts +0 -2
  45. package/dist/v2/types.d.ts +0 -75
@@ -0,0 +1,16 @@
1
+ $ tsup src/index.ts --minify --clean --format cjs,esm --dts
2
+ CLI Building entry: src/index.ts
3
+ CLI Using tsconfig: tsconfig.json
4
+ CLI tsup v8.5.1
5
+ CLI Target: es2022
6
+ CLI Cleaning output folder
7
+ CJS Build start
8
+ ESM Build start
9
+ ESM dist/index.mjs 20.78 KB
10
+ ESM ⚡️ Build success in 108ms
11
+ CJS dist/index.js 22.94 KB
12
+ CJS ⚡️ Build success in 112ms
13
+ DTS Build start
14
+ DTS ⚡️ Build success in 5181ms
15
+ DTS dist/index.d.ts 149.48 KB
16
+ DTS dist/index.d.mts 149.48 KB
package/README.md CHANGED
@@ -1,196 +1,375 @@
1
- # PromptQL NodeJS SDK
1
+ # PromptQL TypeScript SDK
2
2
 
3
- A Node.js SDK for [PromptQL API](https://hasura.io/docs/promptql/promptql-apis/overview/).
3
+ The PromptQL TypeScript SDK is a general-purpose SDK that interacts with the [PromptQL API](https://promptql.hasura.io) by Hasura. PromptQL enables natural language querying of your data through an AI-powered interface.
4
4
 
5
- ## Install
5
+ > [!NOTE]
6
+ > This SDK supports PromptQL v2. Please install [@hasura/promptql@1.0.0](https://www.npmjs.com/package/@hasura/promptql/v/1.0.0) if you wants to integrate PromptQL v1.
6
7
 
7
- Run the following command:
8
+ ## Features
8
9
 
9
- ```sh
10
- npm install @hasura/promptql
10
+ - **Type-safe API Client**: Fully typed TypeScript SDK with auto-generated types from GraphQL schema
11
+ - **Thread Management**: Create, list, and manage conversation threads
12
+ - **Real-time Streaming**: Subscribe to thread events with GraphQL subscriptions using RxJS observables
13
+ - **Authentication**: Built-in authentication handling with service account tokens
14
+ - **Query Planning**: Access to AI agent query plans and execution steps
15
+ - **Artifact Support**: Handle modified artifacts from AI responses
16
+ - **CLI Tool**: Command-line interface for quick interactions
17
+ - **Flexible Configuration**: Support for custom base URLs, headers, and fetch implementations
18
+
19
+ ## Requirements
20
+
21
+ - Node.js >= 24
22
+ - TypeScript >= 5.9.2
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ npm install @hasura/promptql@latest
11
28
  ```
12
29
 
13
- ## Get started
30
+ Or with your preferred package manager:
14
31
 
15
- ### Prerequisite
32
+ ```bash
33
+ # Yarn
34
+ yarn add @hasura/promptql@latest
16
35
 
17
- - If you are new with PromptQL, follow [the quickstart guide of PromptQL](https://hasura.io/docs/promptql/quickstart/) to create a project.
18
- - Create a PromptQL API Key in project settings tab on [https://console.hasura.io](https://console.hasura.io).
19
- - Security headers and your Project API endpoint (version 1) or build version (version 2).
36
+ # pnpm
37
+ pnpm add @hasura/promptql@latest
20
38
 
21
- ### Use PromptQL SDK
39
+ # Bun
40
+ bun add @hasura/promptql@latest
41
+ ```
22
42
 
23
- #### Create client
43
+ ## Quick Start
24
44
 
25
- Create the PromptQL client with required configurations:
45
+ ### Getting Service Account Token
26
46
 
27
- ```ts
28
- import { createPromptQLClientV2 } from '@hasura/promptql';
47
+ 1. Visit your Hasura project console
48
+ 2. Navigate to Project Settings
49
+ 3. Go to Service Accounts section
50
+ 4. Create a new service account token with `Read Only` permission. Avoid using the `Admin` role. Hackers can modify your project metadata if the service account token is leaked.
51
+ 5. Copy the token and use it in your SDK configuration
29
52
 
30
- const client = createPromptQLClientV2({
31
- apiKey: '<your-promptql-api-key>',
32
- ddn: {
33
- headers: {
34
- 'Authorization': '<credential>'
35
- }
36
- },
37
- // You can define a lazy function for the ddn options.
38
- //
39
- // ddn: () => {{
40
- // headers: {
41
- // 'Authorization': '<credential>'
42
- // }
43
- // }}
53
+ For more details, check the [Hasura documentation](https://hasura.io/docs/3.0/project-configuration/project-management/service-accounts/#how-to-create-service-account).
54
+
55
+ ### Basic Usage
56
+
57
+ #### Start a PromptQL thread
58
+
59
+ ```typescript
60
+ import { PromptQLSdk } from '@hasura/promptql';
61
+
62
+ // Initialize the SDK
63
+ const sdk = new PromptQLSdk({
64
+ projectId: 'your-project-id',
65
+ serviceAccountToken: 'your-service-account-token',
44
66
  });
45
- ```
46
67
 
47
- #### Run a Query
48
-
49
- ```ts
50
- const runQuery = (text: string) => {
51
- return client.query({
52
- artifacts: [],
53
- interactions: [
54
- {
55
- user_message: {
56
- text,
57
- }
58
- }
59
- ],
60
- ddn: {
61
- // you can override the default ddn config,
62
- // for example, dynamic auth credentials
63
- headers: {}
64
- }
68
+ // Start a new thread
69
+ const thread = await sdk.startThread({
70
+ message: 'What are the top 10 customers by revenue?',
71
+ });
72
+
73
+ console.log('Thread ID:', thread.thread_id);
74
+
75
+ // Stream events from the thread
76
+ sdk.streamThreadEventsByThreadId(thread.thread_id).subscribe({
77
+ next: (events) => {
78
+ events.forEach(event => {
79
+ console.log('Event:', event);
65
80
  });
81
+ },
82
+ error: (err) => console.error('Error:', err),
83
+ complete: () => console.log('Interaction complete'),
84
+ });
85
+ ```
66
86
 
67
- return response.
68
- }
87
+ #### Continue a Conversation
69
88
 
70
- runQuery('what can you do?').then((response) => {
71
- console.log(response)
89
+ ```typescript
90
+ // Send a follow-up message to an existing thread
91
+ const result = await sdk.sendMessageToThread({
92
+ threadId: 'existing-thread-id',
93
+ message: 'Now show me their average order value',
72
94
  });
95
+
96
+ // Stream the response
97
+ sdk.streamThreadEventsByThreadId(result.thread_id, result.thread_event_id)
98
+ .subscribe({
99
+ next: (events) => console.log('New events:', events),
100
+ });
73
101
  ```
74
102
 
75
- ## Reference
103
+ #### Wait until the final response only
76
104
 
77
- ### Version 2
105
+ Use the `lastValueFrom` function to wrap the subscription.
78
106
 
79
- #### Natural Language
107
+ ```typescript
108
+ import { PromptQLSdk } from '@hasura/promptql';
109
+ import { lastValueFrom } from "rxjs";
80
110
 
81
- The API version 2 simplifies request parameters:
82
- - The DDN URL is replaced by `build_version`.
83
- - `llm`, `ai_primitives_llm`, and `system_instructions` are removed.
111
+ // Initialize the SDK
112
+ const sdk = new PromptQLSdk({
113
+ projectId: 'your-project-id',
114
+ serviceAccountToken: 'your-service-account-token',
115
+ });
84
116
 
85
- To use the API v2, you need to create a PromptQL Client v2:
117
+ // Start a new thread
118
+ const thread = await sdk.startThread({
119
+ message: 'What are the top 10 customers by revenue?',
120
+ });
86
121
 
87
- ```ts
88
- import { createPromptQLClientV2 } from '@hasura/promptql';
122
+ console.log('Thread ID:', thread.thread_id);
89
123
 
90
- const client = createPromptQLClientV2({
91
- apiKey: '<your-promptql-api-key>',
92
- ddn: {
93
- // build_version: '<your-build-version>',
94
- headers: {
95
- 'Authorization': '<credential>'
96
- }
97
- },
124
+ const events = await lastValueFrom(
125
+ sdk.streamThreadEventsByThreadId(
126
+ result.thread_id,
127
+ ),
128
+ );
129
+
130
+ events.forEach(event => {
131
+ console.log('Event:', event);
98
132
  });
99
133
  ```
100
134
 
101
- ##### Non-Streaming
135
+ #### Print new events only
136
+
137
+ ```typescript
138
+ import { PromptQLSdk, diffThreadEvents } from '@hasura/promptql';
139
+ import { pairwise, map } from 'rxjs';
140
+
141
+ // Initialize the SDK
142
+ const sdk = new PromptQLSdk({
143
+ projectId: 'your-project-id',
144
+ serviceAccountToken: 'your-service-account-token',
145
+ });
102
146
 
103
- ```ts
104
- function query(
105
- body: PromptQLQueryRequestV2,
106
- queryOptions?: FetchOptions
107
- ) => Promise<QueryResponse>
147
+ // Start a new thread
148
+ const thread = await sdk.startThread({
149
+ message: 'What are the top 10 customers by revenue?',
150
+ });
151
+
152
+ console.log('Thread ID:', thread.thread_id);
153
+
154
+ // Stream events from the thread
155
+ sdk.streamThreadEventsByThreadId(thread.thread_id)
156
+ .pipe(
157
+ pairwise(),
158
+ map(([prev, curr]) => diffThreadEvents(prev, curr)),
159
+ )
160
+ .subscribe({
161
+ next: (events) => {
162
+ events.forEach(event => {
163
+ console.log('Event:', event);
164
+ });
165
+ },
166
+ error: (err) => console.error('Error:', err),
167
+ complete: () => console.log('Interaction complete'),
168
+ });
108
169
  ```
109
170
 
110
- ##### Streaming
171
+ ### Listing Threads
111
172
 
112
- ```ts
113
- function queryStream(
114
- body: PromptQLQueryRequestV2,
115
- callback?: (data: QueryResponseChunk) => void | Promise<void>,
116
- queryOptions?: FetchOptions
117
- ) Promise<Response>;
173
+ ```typescript
174
+ const threads = await sdk.getThreads({
175
+ limit: 20,
176
+ offset: 0,
177
+ order_by: [{ created_at: 'desc' }],
178
+ where: {
179
+ // Optional filters
180
+ },
181
+ });
182
+
183
+ threads.forEach(thread => {
184
+ console.log(`Thread ${thread.id}:`, thread.title);
185
+ });
118
186
  ```
119
187
 
120
- #### Execute Program
188
+ ### Get a Specific Thread
121
189
 
122
- Execute a PromptQL program with your data.
190
+ ```typescript
191
+ const thread = await sdk.getThreadById('thread-id');
192
+ console.log('Thread:', thread);
193
+ ```
123
194
 
124
- ```ts
125
- function executeProgram: (
126
- body: PromptQLExecuteRequestV2,
127
- executeOptions?: FetchOptions,
128
- ) => Promise<PromptQlExecutionResult>
195
+ ## Event Handling
196
+
197
+ ### Basics
198
+
199
+ The data structure of event data is the union of many event type. Each event type contains a different payload. You can go to the definition of `ThreadEventData` type to view the full data structure details.
200
+
201
+ The SDK also provides utility functions to parse different event types, for example, the following example catches and prints the query plan event and the final generated response:
202
+
203
+ ```typescript
204
+ import {
205
+ getAgentPlanGenerationStartedEvent,
206
+ getAgentPlanStepGeneratedEvent,
207
+ getAgentGeneratedResponse,
208
+ getUserMessageEvent,
209
+ } from '@hasura/promptql';
210
+
211
+ sdk.streamThreadEventsByThreadId(threadId).subscribe({
212
+ next: (events) => {
213
+ events.forEach(event => {
214
+ // Check for plan generation start
215
+ const planStart = getAgentPlanGenerationStartedEvent(event.event_data);
216
+ if (planStart) {
217
+ console.log('Query Plan:\n');
218
+ return;
219
+ }
220
+
221
+ // Check for plan steps
222
+ const planStep = getAgentPlanStepGeneratedEvent(event.event_data);
223
+ if (planStep) {
224
+ console.log(` - Step ${planStep.step_index}: ${planStep.step_title}\n`);
225
+ return;
226
+ }
227
+
228
+ // Check for final response
229
+ const response = getAgentGeneratedResponse(event.event_data);
230
+ if (response) {
231
+ const xmlRegex = /<\w+.*\/>/gm;
232
+ console.log('Response:', source.replaceAll(xmlRegex, response.response.message));
233
+ if (response.response.modified_artifacts) {
234
+ console.log('Artifacts:', response.response.modified_artifacts);
235
+ }
236
+ return;
237
+ }
238
+ });
239
+ },
240
+ });
129
241
  ```
130
242
 
131
- ### Version 1
243
+ ### Handle XML tags in generated response message
244
+
245
+ The generated message may contains XML tags. They represents custom UI elements that the markdown text doesn't support. You should parse or remove them if they aren't required.
132
246
 
133
- #### Natural Language
247
+ Common XML tags are:
134
248
 
135
- The [Natural Language Query API](https://hasura.io/docs/promptql/promptql-apis/natural-language-api/) allows you to interact with PromptQL directly, sending messages and receiving responses.
249
+ - `<artifact type="table" identifier="last_5_products" />`: the identifier of the artifact block.
250
+ - `<user_mention id="user_id" />`: mentioned user in the chat message.
251
+ - `<user_group_mention id="group_id" />`: mentioned group in the chat message.
252
+ - `<promptql_mention />`: represents a `@promptql` tag in the chat message.
136
253
 
137
- ##### Non-Streaming
254
+ You can remove them using regular expressions or parse the message to XML elements for advanced format.
138
255
 
139
- ```ts
140
- function query(
141
- body: PromptQLQueryRequestV1,
142
- queryOptions?: FetchOptions
143
- ) => Promise<QueryResponse>
256
+ ```typescript
257
+ const xmlRegex = /<\w+.*\/>/gm;
258
+ console.log(source.replaceAll(xmlRegex, ""));
144
259
  ```
145
260
 
146
- ##### Streaming
261
+ ## Configuration Options
262
+
263
+ ```typescript
264
+ interface PromptQLSdkOptions {
265
+ // Required: Project ID from PromptQL console
266
+ projectId: string;
267
+
268
+ // Required: Service account token for authentication
269
+ serviceAccountToken: string;
147
270
 
148
- The streaming response sends chunks of data in Server-Sent Events (SSE) format.
149
- If the callback isn't set the client returns the raw response and you need to handle the response manually.
271
+ // Optional: Base URL of PromptQL data plane
272
+ // Default: 'https://promptql.ddn.hasura.app'
273
+ promptqlBaseUrl?: string;
150
274
 
151
- ```ts
152
- function queryStream(
153
- body: PromptQLQueryRequestV1,
154
- callback?: (data: QueryResponseChunk) => void | Promise<void>,
155
- queryOptions?: FetchOptions
156
- ) Promise<Response>;
275
+ // Optional: Custom authentication host (for self-hosted control plane)
276
+ authHost?: string;
277
+
278
+ // Optional: Custom fetch implementation
279
+ fetch?: typeof fetch;
280
+
281
+ // Optional: Additional headers for all requests
282
+ headers?: Record<string, string>;
283
+
284
+ // Optional: IANA timezone for time-based queries
285
+ // Default: Client's timezone
286
+ timezone?: string;
287
+
288
+ // Optional: DDN build ID
289
+ // Default: Applied build
290
+ buildId?: string;
291
+ }
157
292
  ```
158
293
 
159
- Example:
294
+ ## API Reference
160
295
 
161
- ```ts
162
- client
163
- .queryStream({
164
- artifacts: [],
165
- interactions: [
166
- user_message: {
167
- text: 'what can you do?',
168
- }
169
- ],
170
- },
171
- async (chunk) => {
172
- console.log(chunk);
173
- },
174
- );
296
+ ### Class: `PromptQLSdk`
297
+
298
+ #### Constructor
299
+
300
+ ```typescript
301
+ new PromptQLSdk(options: PromptQLSdkOptions)
175
302
  ```
176
303
 
177
- #### Execute Program
304
+ #### Methods
178
305
 
179
- Execute a PromptQL program with your data.
306
+ ##### `getThreads(variables)`
180
307
 
181
- ```ts
182
- function executeProgram: (
183
- body: PromptQLExecuteRequestV1,
184
- executeOptions?: FetchOptions,
185
- ) => Promise<PromptQlExecutionResult>
308
+ List threads with optional filtering and pagination.
309
+
310
+ ```typescript
311
+ getThreads(variables: GetThreadsQueryVariables): Promise<ThreadFragment[]>
186
312
  ```
187
313
 
188
- ## Development
314
+ ##### `getThreadById(threadId)`
189
315
 
190
- ### Generate types
316
+ Get a specific thread by ID.
191
317
 
192
- Use the following command to update TypeScript types of PromptQL APIs from OpenAPI document.
318
+ ```typescript
319
+ getThreadById(threadId: string): Promise<ThreadFragment | null | undefined>
320
+ ```
193
321
 
194
- ```bash
195
- npm run openapi:ts
322
+ ##### `startThread(variables)`
323
+
324
+ Start a new thread with a message.
325
+
326
+ ```typescript
327
+ startThread(variables: StartThreadArguments): Promise<StartThreadOutput>
196
328
  ```
329
+
330
+ ##### `sendMessageToThread(variables)`
331
+
332
+ Send a message to an existing thread.
333
+
334
+ ```typescript
335
+ sendMessageToThread(variables: SendMessageToThreadArguments): Promise<SendMessageToThreadOutput>
336
+ ```
337
+
338
+ ##### `subscribeThreadEventsByThreadId(threadId, threadEventId?)`
339
+
340
+ Subscribe to events from a thread. Continues indefinitely.
341
+
342
+ ```typescript
343
+ subscribeThreadEventsByThreadId(
344
+ threadId: string,
345
+ threadEventId?: string | null
346
+ ): Observable<ThreadEvent[]>
347
+ ```
348
+
349
+ ##### `streamThreadEventsByThreadId(threadId, threadEventId?)`
350
+
351
+ Stream events from a thread. Automatically completes when interaction finishes.
352
+
353
+ ```typescript
354
+ streamThreadEventsByThreadId(
355
+ threadId: string,
356
+ threadEventId?: string | null
357
+ ): Observable<ThreadEvent[]>
358
+ ```
359
+
360
+ ## License
361
+
362
+ Apache License 2.0 - see [LICENSE](LICENSE) file for details.
363
+
364
+ ## Links
365
+
366
+ - [PromptQL Website](https://promptql.hasura.io)
367
+ - [PromptQL Console](https://promptql.console.hasura.io)
368
+ - [Hasura Documentation](https://hasura.io/docs)
369
+
370
+ ## Support
371
+
372
+ For support, please:
373
+
374
+ 1. Check the [documentation](https://promptql.hasura.io)
375
+ 2. Join the [Hasura Discord community](https://discord.gg/hasura)
package/biome.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/2.3.13/schema.json",
3
+ "root": false,
4
+ "files": {
5
+ "includes": ["**/*.ts", "**/*.gql", "!src/generated/*", "!dist/**/*"]
6
+ },
7
+ "extends": ["@hasura/biome-config/base"]
8
+ }