@hasura/promptql 1.0.0 → 2.0.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,196 +1,309 @@
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.thread.start({
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.thread.streamEvents(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.thread.sendMessage({
92
+ threadId: 'existing-thread-id',
93
+ message: 'Now show me their average order value',
72
94
  });
95
+
96
+ // Stream the response
97
+ sdk.streamEvents(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
104
+
105
+ Use the `lastValueFrom` function to wrap the subscription.
76
106
 
77
- ### Version 2
107
+ ```typescript
108
+ import { PromptQLSdk } from '@hasura/promptql';
109
+ import { lastValueFrom } from "rxjs";
78
110
 
79
- #### Natural Language
111
+ // Initialize the SDK
112
+ const sdk = new PromptQLSdk({
113
+ projectId: 'your-project-id',
114
+ serviceAccountToken: 'your-service-account-token',
115
+ });
80
116
 
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.
117
+ // Start a new thread
118
+ const thread = await sdk.thread.start({
119
+ message: 'What are the top 10 customers by revenue?',
120
+ });
84
121
 
85
- To use the API v2, you need to create a PromptQL Client v2:
122
+ console.log('Thread ID:', thread.thread_id);
86
123
 
87
- ```ts
88
- import { createPromptQLClientV2 } from '@hasura/promptql';
124
+ const events = await lastValueFrom(
125
+ sdk.thread.streamEvents(
126
+ result.thread_id,
127
+ ),
128
+ );
89
129
 
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
- },
130
+ events.forEach(event => {
131
+ console.log('Event:', event);
98
132
  });
99
133
  ```
100
134
 
101
- ##### Non-Streaming
135
+ #### Print new events only
102
136
 
103
- ```ts
104
- function query(
105
- body: PromptQLQueryRequestV2,
106
- queryOptions?: FetchOptions
107
- ) => Promise<QueryResponse>
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
+ });
146
+
147
+ // Start a new thread
148
+ const thread = await sdk.thread.start({
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.streamEvents(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.thread.list({
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.thread.get('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.thread.streamEvents(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
147
262
 
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.
263
+ ```typescript
264
+ interface PromptQLSdkOptions {
265
+ // Required: Project ID from PromptQL console
266
+ projectId: string;
150
267
 
151
- ```ts
152
- function queryStream(
153
- body: PromptQLQueryRequestV1,
154
- callback?: (data: QueryResponseChunk) => void | Promise<void>,
155
- queryOptions?: FetchOptions
156
- ) Promise<Response>;
157
- ```
268
+ // Required: Service account token for authentication
269
+ serviceAccountToken: string;
158
270
 
159
- Example:
160
-
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
- );
175
- ```
271
+ // Optional: Base URL of PromptQL data plane
272
+ // Default: 'https://promptql.ddn.hasura.app'
273
+ promptqlBaseUrl?: string;
274
+
275
+ // Optional: Custom authentication host (for self-hosted control plane)
276
+ authHost?: string;
277
+
278
+ // Optional: Custom fetch implementation
279
+ fetch?: typeof fetch;
176
280
 
177
- #### Execute Program
281
+ // Optional: Additional headers for all requests
282
+ headers?: Record<string, string>;
178
283
 
179
- Execute a PromptQL program with your data.
284
+ // Optional: IANA timezone for time-based queries
285
+ // Default: Client's timezone
286
+ timezone?: string;
180
287
 
181
- ```ts
182
- function executeProgram: (
183
- body: PromptQLExecuteRequestV1,
184
- executeOptions?: FetchOptions,
185
- ) => Promise<PromptQlExecutionResult>
288
+ // Optional: DDN build ID
289
+ // Default: Applied build
290
+ buildId?: string;
291
+ }
186
292
  ```
187
293
 
188
- ## Development
294
+ ## License
189
295
 
190
- ### Generate types
296
+ Apache License 2.0 - see [LICENSE](LICENSE) file for details.
191
297
 
192
- Use the following command to update TypeScript types of PromptQL APIs from OpenAPI document.
298
+ ## Links
193
299
 
194
- ```bash
195
- npm run openapi:ts
196
- ```
300
+ - [PromptQL Website](https://promptql.hasura.io)
301
+ - [PromptQL Console](https://promptql.console.hasura.io)
302
+ - [Hasura Documentation](https://hasura.io/docs)
303
+
304
+ ## Support
305
+
306
+ For support, please:
307
+
308
+ 1. Check the [documentation](https://promptql.hasura.io)
309
+ 2. Join the [Hasura Discord community](https://discord.gg/hasura)
package/biome.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/2.3.13/schema.json",
3
+ "root": false,
4
+ "files": {
5
+ "includes": [
6
+ "**/*.ts",
7
+ "**/*.gql",
8
+ "!src/generated/*",
9
+ "!dist/**/*"
10
+ ]
11
+ },
12
+ "extends": [
13
+ "../biome-config/base.json"
14
+ ]
15
+ }