@hasura/promptql 2.0.0-alpha.1 → 2.0.0-alpha.3

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.
@@ -1,70 +0,0 @@
1
- # GraphQL Operations
2
-
3
- This directory contains GraphQL operations (queries, mutations, and fragments)
4
- that are used by the chat-handler service.
5
-
6
- ## Directory Structure
7
-
8
- ```
9
- graphql/
10
- ├── queries/ # GraphQL queries
11
- ├── mutations/ # GraphQL mutations
12
- └── fragments/ # Reusable GraphQL fragments
13
- ```
14
-
15
- ## How to Use
16
-
17
- ### 1. Define Operations
18
-
19
- Create `.gql` files in the appropriate directory:
20
-
21
- **queries/getUser.gql**
22
-
23
- ```graphql
24
- query GetUser($userId: uuid!) {
25
- users_by_pk(id: $userId) {
26
- id
27
- email
28
- name
29
- }
30
- }
31
- ```
32
-
33
- ### 2. Generate Types
34
-
35
- Run the code generator to create TypeScript types:
36
-
37
- ```bash
38
- bun run codegen
39
- ```
40
-
41
- This will generate typed operations in `src/generated/graphql.ts`.
42
-
43
- ### 3. Use in Code
44
-
45
- Import and use the generated SDK:
46
-
47
- ```typescript
48
- import { createHGEClient } from "../hge-client";
49
-
50
- const sdk = createHGEClient();
51
-
52
- // Fully typed query with autocomplete and type checking
53
- const result = await sdk.GetUser({ userId: "123" });
54
- console.log(result.users_by_pk?.name);
55
- ```
56
-
57
- ## Benefits
58
-
59
- - **Type Safety**: All operations are fully typed
60
- - **Autocomplete**: IDE provides autocomplete for all fields
61
- - **Validation**: Operations are validated against the schema at build time
62
- - **Refactoring**: Renaming fields in the schema automatically updates all
63
- usages
64
-
65
- ## Environment Variables
66
-
67
- Make sure to set these environment variables:
68
-
69
- - `PLAYGROUND_GRAPHQL_URI`: The GraphQL API endpoint URL
70
- - `PLAYGROUND_GRAPHQL_ADMIN_SECRET`: The admin secret for authentication
@@ -1,16 +0,0 @@
1
- mutation SendThreadMessage(
2
- $message: String!
3
- $timezone: String!
4
- $threadId: String!
5
- $buildFqdn: String
6
- ) {
7
- send_thread_message(
8
- threadId: $threadId
9
- timezone: $timezone
10
- message: $message
11
- buildFqdn: $buildFqdn
12
- ) {
13
- thread_event_id
14
- created_at
15
- }
16
- }
@@ -1,19 +0,0 @@
1
- mutation StartThread(
2
- $message: String!
3
- $projectId: String!
4
- $timezone: String!
5
- $buildId: String
6
- $buildFqdn: String
7
- ) {
8
- start_thread(
9
- message: $message
10
- projectId: $projectId
11
- timezone: $timezone
12
- buildId: $buildId
13
- buildFqdn: $buildFqdn
14
- ) {
15
- thread_id
16
- title
17
- created_at
18
- }
19
- }
@@ -1,7 +0,0 @@
1
- query GetProjectInfo($projectId: uuid!) {
2
- get_project_info(projectId: $projectId) {
3
- projectId
4
- projectName
5
- promptqlConsoleUrl
6
- }
7
- }
@@ -1,39 +0,0 @@
1
- fragment Thread on threads_v2 {
2
- thread_id
3
- build_id
4
- title
5
- relevant_event_count
6
- visibility
7
- created_at
8
- updated_at
9
- user {
10
- promptql_user_id
11
- display_name
12
- email
13
- is_active
14
- created_at
15
- updated_at
16
- }
17
- }
18
-
19
- query GetThreads(
20
- $where: threads_v2_bool_exp!
21
- $limit: Int
22
- $offset: Int
23
- $order_by: [threads_v2_order_by!]
24
- ) {
25
- threads_v2(
26
- where: $where
27
- limit: $limit
28
- offset: $offset
29
- order_by: $order_by
30
- ) {
31
- ...Thread
32
- }
33
- }
34
-
35
- query GetThreadById($id: uuid!) {
36
- threads_v2_by_pk(thread_id: $id) {
37
- ...Thread
38
- }
39
- }
@@ -1,7 +0,0 @@
1
- subscription SubscribeThreadEvents($where: thread_events_bool_exp!) {
2
- thread_events(where: $where, order_by: { thread_event_id: asc }) {
3
- thread_event_id
4
- event_data
5
- created_at
6
- }
7
- }
package/src/index.ts DELETED
@@ -1,13 +0,0 @@
1
- import type { ThreadEvent as ThreadEventData } from "./generated/ChatV2ServerTypes";
2
- import type { ThreadEvent } from "./sdk";
3
-
4
- export * from "./auth";
5
- export * from "./generated/ChatV2ServerTypes";
6
- export type {
7
- GetThreadsQueryVariables,
8
- Order_By,
9
- ThreadFragment,
10
- } from "./generated/graphql";
11
- export * from "./sdk";
12
-
13
- export type { ThreadEvent, ThreadEventData };
package/src/sdk/apollo.ts DELETED
@@ -1,63 +0,0 @@
1
- import {
2
- ApolloClient,
3
- ApolloLink,
4
- HttpLink,
5
- InMemoryCache,
6
- } from "@apollo/client";
7
- import { SetContextLink } from "@apollo/client/link/context";
8
- import { GraphQLWsLink } from "@apollo/client/link/subscriptions";
9
- import { OperationTypeNode } from "graphql";
10
- import { createClient } from "graphql-ws";
11
-
12
- export type ApolloClientOptions = {
13
- url: string;
14
- headers?: Record<string, string>;
15
- getAuthToken: () => Promise<string>;
16
- fetch?: typeof fetch;
17
- };
18
-
19
- export const createApolloClient = (options: ApolloClientOptions) => {
20
- const httpLink = new HttpLink({
21
- uri: options.url,
22
- fetch: options.fetch,
23
- headers: options.headers,
24
- });
25
-
26
- const setAuthContext = async (headers?: Record<string, string>) => {
27
- const token = await options.getAuthToken();
28
-
29
- return {
30
- headers: {
31
- ...headers,
32
- Authorization: `Bearer ${token}`,
33
- },
34
- };
35
- };
36
-
37
- const wsLink = new GraphQLWsLink(
38
- createClient({
39
- url: options.url,
40
- connectionParams: () => setAuthContext(options.headers),
41
- }),
42
- );
43
-
44
- const authLink = new SetContextLink(({ headers }) => setAuthContext(headers));
45
-
46
- // The split function takes three parameters:
47
- //
48
- // * A function that's called for each operation to execute
49
- // * The Link to use for an operation if the function returns a "truthy" value
50
- // * The Link to use for an operation if the function returns a "falsy" value
51
- const splitLink = ApolloLink.split(
52
- ({ operationType }) => {
53
- return operationType === OperationTypeNode.SUBSCRIPTION;
54
- },
55
- wsLink,
56
- authLink.concat(httpLink),
57
- );
58
-
59
- return new ApolloClient({
60
- link: splitLink,
61
- cache: new InMemoryCache(),
62
- });
63
- };
package/src/sdk/client.ts DELETED
@@ -1,273 +0,0 @@
1
- import type { ApolloClient, Observable } from "@apollo/client";
2
- import { map, takeWhile } from "rxjs/operators";
3
- import { createPromptQLAuthTokenGenerator } from "../auth/auth";
4
- import {
5
- GetProjectInfoDocument,
6
- type GetProjectInfoOutput,
7
- GetThreadByIdDocument,
8
- GetThreadsDocument,
9
- type GetThreadsQueryVariables,
10
- SendThreadMessageDocument,
11
- StartThreadDocument,
12
- SubscribeThreadEventsDocument,
13
- Thread_Events_Bool_Exp,
14
- type ThreadFragment,
15
- } from "../generated/graphql";
16
- import { normalizeBaseUrl } from "../utils";
17
- import { createApolloClient } from "./apollo";
18
- import type {
19
- PromptQLSdkOptions,
20
- SendMessageToThreadArguments,
21
- SendMessageToThreadOutput,
22
- StartThreadArguments,
23
- StartThreadOutput,
24
- ThreadEvent,
25
- } from "./types";
26
-
27
- /**
28
- * PromptQL SDK allows you to interact with PromptQL API.
29
- */
30
- export class PromptQLSdk {
31
- constructor(options: PromptQLSdkOptions) {
32
- const promptqlBaseUrl =
33
- normalizeBaseUrl(options.promptqlBaseUrl) ||
34
- "https://promptql.ddn.hasura.app";
35
-
36
- if (!options.projectId) {
37
- throw new Error(
38
- "projectId must not be empty. You can find it in Project Settings > General Settings tab on https://promptql.console.hasura.io.",
39
- );
40
- }
41
-
42
- if (!options.serviceAccountToken) {
43
- throw new Error(
44
- "serviceAccountToken must not be empty. If you haven't created any service account token yet, check out Hasura docs https://hasura.io/docs/3.0/project-configuration/project-management/service-accounts/#how-to-create-service-account",
45
- );
46
- }
47
-
48
- const promptqlGraphQLUrl = promptqlBaseUrl.endsWith("/v1/graphql")
49
- ? promptqlBaseUrl
50
- : `${promptqlBaseUrl}/playground-v2-hge/v1/graphql`;
51
-
52
- const authFetcher = createPromptQLAuthTokenGenerator({
53
- promptqlGraphQLUrl,
54
- authHost: options.authHost,
55
- projectId: options.projectId,
56
- serviceAccountToken: options.serviceAccountToken,
57
- fetch: options.fetch,
58
- });
59
-
60
- this.projectId = options.projectId;
61
- this.buildId = options.buildId;
62
-
63
- this.client = createApolloClient({
64
- getAuthToken: authFetcher,
65
- url: promptqlGraphQLUrl,
66
- fetch: options.fetch,
67
- headers: options.headers,
68
- });
69
-
70
- this.defaultTimezone =
71
- options.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone;
72
- }
73
-
74
- private client: ApolloClient;
75
- private projectId: string;
76
- private buildId: string | undefined;
77
- private defaultTimezone: string;
78
-
79
- /**
80
- * Get the basic information of the PromptQL project.
81
- */
82
- public getProjectInfo(): Promise<GetProjectInfoOutput> {
83
- return this.client
84
- .query({
85
- query: GetProjectInfoDocument,
86
- variables: {
87
- projectId: this.projectId,
88
- },
89
- })
90
- .then((result) => {
91
- if (!result.data?.get_project_info) {
92
- throw new Error(result.error?.message || "Project not found");
93
- }
94
-
95
- return result.data.get_project_info;
96
- });
97
- }
98
-
99
- /**
100
- * List threads of the current project. The default limit is 10.
101
- */
102
- public getThreads(
103
- variables: GetThreadsQueryVariables,
104
- ): Promise<ThreadFragment[]> {
105
- return this.client
106
- .query({
107
- query: GetThreadsDocument,
108
- variables: {
109
- ...variables,
110
- limit: variables.limit && variables.limit > 0 ? variables.limit : 10,
111
- },
112
- fetchPolicy: "no-cache",
113
- })
114
- .then((result) => result.data?.threads_v2 ?? []);
115
- }
116
-
117
- /**
118
- * Get a thread by ID.
119
- */
120
- public getThreadById(
121
- threadId: string,
122
- ): Promise<ThreadFragment | null | undefined> {
123
- if (!threadId) {
124
- throw new Error("threadId is required");
125
- }
126
-
127
- return this.client
128
- .query({
129
- query: GetThreadByIdDocument,
130
- variables: {
131
- id: threadId,
132
- },
133
- fetchPolicy: "no-cache",
134
- })
135
- .then((result) => result.data?.threads_v2_by_pk);
136
- }
137
-
138
- /**
139
- * Start a PromptQL thread.
140
- */
141
- public startThread(
142
- variables: StartThreadArguments,
143
- ): Promise<StartThreadOutput> {
144
- if (!variables.message.trim()) {
145
- throw new Error("message must not be empty");
146
- }
147
-
148
- return this.client
149
- .mutate({
150
- mutation: StartThreadDocument,
151
- variables: {
152
- ...variables,
153
- projectId: this.projectId,
154
- buildId: variables.buildId || this.buildId,
155
- timezone: variables.timezone || this.defaultTimezone,
156
- },
157
- })
158
- .then((result) => {
159
- if (!result.data?.start_thread) {
160
- throw new Error(result.error?.message || "Failed to start thread");
161
- }
162
-
163
- return result.data.start_thread;
164
- });
165
- }
166
-
167
- /**
168
- * Send a message to an existing thread.
169
- */
170
- public sendMessageToThread(
171
- variables: SendMessageToThreadArguments,
172
- ): Promise<SendMessageToThreadOutput> {
173
- if (!variables.threadId) {
174
- throw new Error("threadId is required");
175
- }
176
-
177
- if (!variables.message.trim()) {
178
- throw new Error("message must not be empty");
179
- }
180
-
181
- return this.client
182
- .mutate({
183
- mutation: SendThreadMessageDocument,
184
- variables: {
185
- ...variables,
186
- timezone: variables.timezone || this.defaultTimezone,
187
- },
188
- })
189
- .then((result) => {
190
- if (!result.data?.send_thread_message) {
191
- throw new Error(result.error?.message || "Failed to continue thread");
192
- }
193
-
194
- return result.data.send_thread_message;
195
- });
196
- }
197
-
198
- /**
199
- * Subscribe to events of a thread by ID. The subscription won't stop even if the interaction is completed.
200
- */
201
- public subscribeThreadEventsByThreadId(
202
- threadId: string,
203
- threadEventId?: string | null,
204
- ): Observable<ThreadEvent[]> {
205
- if (!threadId) {
206
- throw new Error("threadId is required");
207
- }
208
-
209
- if (threadEventId !== null && threadEventId !== undefined) {
210
- try {
211
- Number.parseInt(threadEventId);
212
- } catch {
213
- throw new Error("invalid threadEventId");
214
- }
215
- }
216
-
217
- const where: Thread_Events_Bool_Exp = {
218
- thread_id: { _eq: threadId },
219
- };
220
-
221
- if (threadEventId) {
222
- where.thread_event_id = {
223
- _gte: threadEventId,
224
- };
225
- }
226
-
227
- return this.client
228
- .subscribe({
229
- query: SubscribeThreadEventsDocument,
230
- variables: {
231
- where,
232
- },
233
- })
234
- .pipe(
235
- map((value) => {
236
- if (value.error) {
237
- throw value.error;
238
- }
239
-
240
- return (value.data?.thread_events ?? []) as ThreadEvent[];
241
- }),
242
- );
243
- }
244
-
245
- /**
246
- * Stream events of a thread by ID. Stop the subscription right after received the completed event.
247
- */
248
- public streamThreadEventsByThreadId(
249
- threadId: string,
250
- threadEventId?: string | null,
251
- ): Observable<ThreadEvent[]> {
252
- return this.subscribeThreadEventsByThreadId(threadId, threadEventId).pipe(
253
- takeWhile((events) => {
254
- for (let i = events.length - 1; i > 0; i--) {
255
- const event = events[i]!;
256
- if (
257
- "AgentMessage" in event.event_data &&
258
- "InteractionFinished" in event.event_data.AgentMessage.update
259
- ) {
260
- return false;
261
- }
262
- }
263
-
264
- return true;
265
- }, true),
266
- );
267
- }
268
- }
269
-
270
- /**
271
- * The interface of PromptQLSdk
272
- */
273
- export type IPromptQLSdk = InstanceType<typeof PromptQLSdk>;
package/src/sdk/index.ts DELETED
@@ -1,4 +0,0 @@
1
- export * from "./apollo";
2
- export * from "./client";
3
- export * from "./types";
4
- export * from "./utils";