@syfthub/sdk 0.1.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.
@@ -0,0 +1,2212 @@
1
+ /**
2
+ * Options for HTTP requests.
3
+ */
4
+ interface RequestOptions {
5
+ /** Whether to include the Authorization header (default: true) */
6
+ includeAuth?: boolean;
7
+ /** Whether to send body as form-urlencoded instead of JSON */
8
+ isFormData?: boolean;
9
+ /** Request-specific timeout in milliseconds */
10
+ timeout?: number;
11
+ }
12
+ /**
13
+ * Auth tokens returned from login/refresh.
14
+ */
15
+ interface AuthTokens {
16
+ accessToken: string;
17
+ refreshToken: string;
18
+ tokenType: string;
19
+ }
20
+ /**
21
+ * Internal HTTP client for making API requests.
22
+ *
23
+ * Handles:
24
+ * - Bearer token authentication
25
+ * - Automatic token refresh on 401 responses
26
+ * - JSON serialization/deserialization
27
+ * - snake_case <-> camelCase conversion
28
+ * - Error handling and exception mapping
29
+ */
30
+ declare class HTTPClient {
31
+ private readonly baseUrl;
32
+ private readonly timeout;
33
+ private accessToken;
34
+ private refreshToken;
35
+ private isRefreshing;
36
+ private refreshPromise;
37
+ /**
38
+ * Create a new HTTP client.
39
+ *
40
+ * @param baseUrl - Base URL for all API requests (without trailing slash)
41
+ * @param timeout - Default timeout in milliseconds (default: 30000)
42
+ */
43
+ constructor(baseUrl: string, timeout?: number);
44
+ /**
45
+ * Set authentication tokens.
46
+ */
47
+ setTokens(access: string, refresh: string): void;
48
+ /**
49
+ * Get current authentication tokens.
50
+ */
51
+ getTokens(): AuthTokens | null;
52
+ /**
53
+ * Clear authentication tokens.
54
+ */
55
+ clearTokens(): void;
56
+ /**
57
+ * Check if the client has valid tokens.
58
+ */
59
+ hasTokens(): boolean;
60
+ /**
61
+ * Make a GET request.
62
+ */
63
+ get<T>(path: string, params?: Record<string, unknown>, options?: RequestOptions): Promise<T>;
64
+ /**
65
+ * Make a POST request.
66
+ */
67
+ post<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
68
+ /**
69
+ * Make a PUT request.
70
+ */
71
+ put<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
72
+ /**
73
+ * Make a PATCH request.
74
+ */
75
+ patch<T>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
76
+ /**
77
+ * Make a DELETE request.
78
+ */
79
+ delete<T>(path: string, options?: RequestOptions): Promise<T>;
80
+ /**
81
+ * Make an HTTP request with automatic retry on 401.
82
+ */
83
+ private request;
84
+ /**
85
+ * Handle the HTTP response and convert to the expected type.
86
+ */
87
+ private handleResponse;
88
+ /**
89
+ * Handle error responses by throwing appropriate exceptions.
90
+ */
91
+ private handleErrorResponse;
92
+ /**
93
+ * Extract error code and detail from API response.
94
+ * Used for accounting-specific error handling.
95
+ */
96
+ private extractErrorCodeAndDetail;
97
+ /**
98
+ * Extract error message from API response.
99
+ */
100
+ private extractErrorMessage;
101
+ /**
102
+ * Extract field-level validation errors from API response.
103
+ */
104
+ private extractValidationErrors;
105
+ /**
106
+ * Attempt to refresh the access token using the refresh token.
107
+ */
108
+ private attemptTokenRefresh;
109
+ }
110
+
111
+ /**
112
+ * Visibility levels for endpoints.
113
+ */
114
+ declare const Visibility: {
115
+ /** Visible to everyone, no authentication required */
116
+ readonly PUBLIC: "public";
117
+ /** Only visible to the owner and collaborators */
118
+ readonly PRIVATE: "private";
119
+ /** Visible to authenticated users within the organization */
120
+ readonly INTERNAL: "internal";
121
+ };
122
+ type Visibility = (typeof Visibility)[keyof typeof Visibility];
123
+ /**
124
+ * Types of endpoints.
125
+ */
126
+ declare const EndpointType: {
127
+ /** Machine learning model endpoint */
128
+ readonly MODEL: "model";
129
+ /** Data source endpoint */
130
+ readonly DATA_SOURCE: "data_source";
131
+ };
132
+ type EndpointType = (typeof EndpointType)[keyof typeof EndpointType];
133
+ /**
134
+ * User roles in the system.
135
+ */
136
+ declare const UserRole: {
137
+ /** Administrator with full access */
138
+ readonly ADMIN: "admin";
139
+ /** Regular user */
140
+ readonly USER: "user";
141
+ /** Guest user with limited access */
142
+ readonly GUEST: "guest";
143
+ };
144
+ type UserRole = (typeof UserRole)[keyof typeof UserRole];
145
+ /**
146
+ * Organization member roles.
147
+ */
148
+ declare const OrganizationRole: {
149
+ /** Organization owner with full control */
150
+ readonly OWNER: "owner";
151
+ /** Administrator with management privileges */
152
+ readonly ADMIN: "admin";
153
+ /** Regular member */
154
+ readonly MEMBER: "member";
155
+ };
156
+ type OrganizationRole = (typeof OrganizationRole)[keyof typeof OrganizationRole];
157
+
158
+ /**
159
+ * User account information.
160
+ */
161
+ interface User {
162
+ readonly id: number;
163
+ readonly username: string;
164
+ readonly email: string;
165
+ readonly fullName: string;
166
+ readonly avatarUrl: string | null;
167
+ readonly role: UserRole;
168
+ readonly isActive: boolean;
169
+ readonly createdAt: Date;
170
+ readonly updatedAt: Date | null;
171
+ /** Domain for endpoint URL construction (e.g., "api.example.com" or "api.example.com:8080") */
172
+ readonly domain: string | null;
173
+ }
174
+ /**
175
+ * Input for user registration.
176
+ */
177
+ interface UserRegisterInput {
178
+ username: string;
179
+ email: string;
180
+ password: string;
181
+ fullName: string;
182
+ /** Optional accounting service URL (can be set up later in settings) */
183
+ accountingServiceUrl?: string;
184
+ /**
185
+ * Optional password for the accounting service account.
186
+ *
187
+ * The backend uses a "try-create-first" approach:
188
+ * - **If provided (new user)**: Creates a new accounting account with this password.
189
+ * - **If provided (existing user)**: Validates against the existing account and links it.
190
+ * - **If not provided**: Auto-generates a secure password for a new account.
191
+ *
192
+ * This means you can set your own accounting password during registration
193
+ * without needing an existing accounting account.
194
+ */
195
+ accountingPassword?: string;
196
+ }
197
+ /**
198
+ * Input for updating user profile.
199
+ */
200
+ interface UserUpdateInput {
201
+ username?: string;
202
+ email?: string;
203
+ fullName?: string;
204
+ avatarUrl?: string;
205
+ /** Domain for endpoint URL construction (no protocol, e.g., "api.example.com:8080") */
206
+ domain?: string;
207
+ }
208
+ /**
209
+ * Input for changing password.
210
+ */
211
+ interface PasswordChangeInput {
212
+ currentPassword: string;
213
+ newPassword: string;
214
+ }
215
+ /**
216
+ * Credentials for connecting to an external accounting service.
217
+ * These are stored in the SyftHub backend and fetched via API.
218
+ */
219
+ interface AccountingCredentials {
220
+ /** URL of the accounting service API (null if not configured) */
221
+ readonly url: string | null;
222
+ /** Email for authenticating with the accounting service (same as SyftHub email) */
223
+ readonly email: string;
224
+ /** Password for authenticating with the accounting service (null if not configured) */
225
+ readonly password: string | null;
226
+ }
227
+
228
+ /**
229
+ * Policy configuration for an endpoint.
230
+ */
231
+ interface Policy {
232
+ readonly type: string;
233
+ readonly version: string;
234
+ readonly enabled: boolean;
235
+ readonly description: string;
236
+ readonly config: Record<string, unknown>;
237
+ }
238
+ /**
239
+ * Connection configuration for an endpoint.
240
+ */
241
+ interface Connection {
242
+ readonly type: string;
243
+ readonly enabled: boolean;
244
+ readonly description: string;
245
+ readonly config: Record<string, unknown>;
246
+ }
247
+ /**
248
+ * Full endpoint model (for authenticated users viewing their own endpoints).
249
+ */
250
+ interface Endpoint {
251
+ readonly id: number;
252
+ readonly userId: number | null;
253
+ readonly organizationId: number | null;
254
+ readonly name: string;
255
+ readonly slug: string;
256
+ readonly description: string;
257
+ readonly type: EndpointType;
258
+ readonly visibility: Visibility;
259
+ readonly isActive: boolean;
260
+ readonly contributors: readonly number[];
261
+ readonly version: string;
262
+ readonly readme: string;
263
+ readonly tags: readonly string[];
264
+ readonly starsCount: number;
265
+ readonly policies: readonly Policy[];
266
+ readonly connect: readonly Connection[];
267
+ readonly createdAt: Date;
268
+ readonly updatedAt: Date;
269
+ }
270
+ /**
271
+ * Public endpoint model (for browsing the hub).
272
+ */
273
+ interface EndpointPublic {
274
+ readonly name: string;
275
+ readonly slug: string;
276
+ readonly description: string;
277
+ readonly type: EndpointType;
278
+ readonly ownerUsername: string;
279
+ /** Number of contributors (user IDs not exposed for privacy) */
280
+ readonly contributorsCount: number;
281
+ readonly version: string;
282
+ readonly readme: string;
283
+ readonly tags: readonly string[];
284
+ readonly starsCount: number;
285
+ readonly policies: readonly Policy[];
286
+ readonly connect: readonly Connection[];
287
+ readonly createdAt: Date;
288
+ readonly updatedAt: Date;
289
+ }
290
+ /**
291
+ * Input for creating a new endpoint.
292
+ */
293
+ interface EndpointCreateInput {
294
+ name: string;
295
+ type: EndpointType;
296
+ visibility?: Visibility;
297
+ description?: string;
298
+ slug?: string;
299
+ version?: string;
300
+ readme?: string;
301
+ tags?: string[];
302
+ policies?: Policy[];
303
+ connect?: Connection[];
304
+ contributors?: number[];
305
+ }
306
+ /**
307
+ * Input for updating an existing endpoint.
308
+ */
309
+ interface EndpointUpdateInput {
310
+ name?: string;
311
+ description?: string;
312
+ visibility?: Visibility;
313
+ version?: string;
314
+ readme?: string;
315
+ tags?: string[];
316
+ policies?: Policy[];
317
+ connect?: Connection[];
318
+ contributors?: number[];
319
+ }
320
+ /**
321
+ * Get the owner type for an endpoint.
322
+ *
323
+ * @param endpoint - The endpoint to check
324
+ * @returns 'user' if user-owned, 'organization' if org-owned
325
+ */
326
+ declare function getEndpointOwnerType(endpoint: Endpoint): 'user' | 'organization';
327
+ /**
328
+ * Get the full path for a public endpoint (owner/slug format).
329
+ *
330
+ * @param endpoint - The public endpoint
331
+ * @returns The path in "owner/slug" format
332
+ */
333
+ declare function getEndpointPublicPath(endpoint: EndpointPublic): string;
334
+
335
+ /**
336
+ * Accounting Models
337
+ *
338
+ * Models for the external accounting service. The accounting service manages
339
+ * user balances and transactions, and uses its own authentication separate
340
+ * from SyftHub.
341
+ */
342
+ /**
343
+ * Transaction status in the accounting service.
344
+ */
345
+ declare const TransactionStatus: {
346
+ /** Transaction created, awaiting confirmation */
347
+ readonly PENDING: "pending";
348
+ /** Transaction confirmed, funds transferred */
349
+ readonly COMPLETED: "completed";
350
+ /** Transaction cancelled, no funds transferred */
351
+ readonly CANCELLED: "cancelled";
352
+ };
353
+ type TransactionStatus = (typeof TransactionStatus)[keyof typeof TransactionStatus];
354
+ /**
355
+ * Who created or resolved a transaction.
356
+ */
357
+ declare const CreatorType: {
358
+ /** System-initiated transaction */
359
+ readonly SYSTEM: "system";
360
+ /** Sender-initiated transaction */
361
+ readonly SENDER: "sender";
362
+ /** Recipient-initiated transaction (delegated) */
363
+ readonly RECIPIENT: "recipient";
364
+ };
365
+ type CreatorType = (typeof CreatorType)[keyof typeof CreatorType];
366
+ /**
367
+ * User from accounting service with balance.
368
+ *
369
+ * This represents the user's account in the external accounting service,
370
+ * which is separate from the SyftHub user account.
371
+ */
372
+ interface AccountingUser {
373
+ readonly id: string;
374
+ readonly email: string;
375
+ readonly balance: number;
376
+ readonly organization: string | null;
377
+ }
378
+ /**
379
+ * Transaction record from accounting service.
380
+ *
381
+ * Transactions go through a lifecycle:
382
+ * 1. Created (status=PENDING)
383
+ * 2. Confirmed or Cancelled (status=COMPLETED or CANCELLED)
384
+ *
385
+ * The createdBy field indicates who initiated the transaction:
386
+ * - SENDER: Direct transaction by the payer
387
+ * - RECIPIENT: Delegated transaction using a token
388
+ * - SYSTEM: System-initiated transaction
389
+ *
390
+ * The resolvedBy field indicates who confirmed/cancelled.
391
+ */
392
+ interface Transaction {
393
+ readonly id: string;
394
+ readonly senderEmail: string;
395
+ readonly recipientEmail: string;
396
+ readonly amount: number;
397
+ readonly status: TransactionStatus;
398
+ readonly createdBy: CreatorType;
399
+ readonly resolvedBy: CreatorType | null;
400
+ readonly createdAt: Date;
401
+ readonly resolvedAt: Date | null;
402
+ readonly appName: string | null;
403
+ readonly appEpPath: string | null;
404
+ }
405
+ /**
406
+ * Input for creating a direct transaction.
407
+ */
408
+ interface CreateTransactionInput {
409
+ /** Email of the recipient */
410
+ recipientEmail: string;
411
+ /** Amount to transfer (must be > 0) */
412
+ amount: number;
413
+ /** Optional app name for context (e.g., "syftai-space") */
414
+ appName?: string;
415
+ /** Optional endpoint path for context (e.g., "alice/model") */
416
+ appEpPath?: string;
417
+ }
418
+ /**
419
+ * Input for creating a delegated transaction.
420
+ */
421
+ interface CreateDelegatedTransactionInput {
422
+ /** Email of the sender who created the token */
423
+ senderEmail: string;
424
+ /** Amount to transfer (must be > 0) */
425
+ amount: number;
426
+ /** JWT token from sender's createTransactionToken() */
427
+ token: string;
428
+ }
429
+ /**
430
+ * Input for updating password.
431
+ */
432
+ interface UpdatePasswordInput {
433
+ /** Current password for verification */
434
+ currentPassword: string;
435
+ /** New password to set */
436
+ newPassword: string;
437
+ }
438
+ /**
439
+ * Raw transaction response from API (before date parsing).
440
+ */
441
+ interface TransactionResponse {
442
+ id: string;
443
+ senderEmail: string;
444
+ recipientEmail: string;
445
+ amount: number;
446
+ status: TransactionStatus;
447
+ createdBy: CreatorType;
448
+ resolvedBy: CreatorType | null;
449
+ createdAt: string;
450
+ resolvedAt: string | null;
451
+ appName: string | null;
452
+ appEpPath: string | null;
453
+ }
454
+ /**
455
+ * Token response from createTransactionToken.
456
+ */
457
+ interface TransactionTokenResponse {
458
+ token: string;
459
+ }
460
+ /**
461
+ * Parse a transaction response into a Transaction object.
462
+ */
463
+ declare function parseTransaction(response: TransactionResponse): Transaction;
464
+ /**
465
+ * Check if a transaction is pending.
466
+ */
467
+ declare function isTransactionPending(tx: Transaction): boolean;
468
+ /**
469
+ * Check if a transaction is completed.
470
+ */
471
+ declare function isTransactionCompleted(tx: Transaction): boolean;
472
+ /**
473
+ * Check if a transaction is cancelled.
474
+ */
475
+ declare function isTransactionCancelled(tx: Transaction): boolean;
476
+
477
+ /**
478
+ * Chat-related types for the SyftHub SDK.
479
+ *
480
+ * These types are used for interacting with the Aggregator service
481
+ * for RAG (Retrieval-Augmented Generation) workflows.
482
+ */
483
+ /**
484
+ * Reference to a SyftAI-Space endpoint with connection details.
485
+ *
486
+ * Can be constructed directly or resolved from an EndpointPublic object.
487
+ *
488
+ * @example
489
+ * const ref: EndpointRef = {
490
+ * url: 'http://syftai-space:8080',
491
+ * slug: 'my-model',
492
+ * name: 'My Model',
493
+ * ownerUsername: 'alice',
494
+ * };
495
+ */
496
+ interface EndpointRef {
497
+ /** Base URL of the SyftAI-Space instance */
498
+ url: string;
499
+ /** Endpoint slug for the API path */
500
+ slug: string;
501
+ /** Display name of the endpoint */
502
+ name?: string;
503
+ /** Tenant name for X-Tenant-Name header */
504
+ tenantName?: string;
505
+ /** Owner's username - used as the audience for satellite token authentication */
506
+ ownerUsername?: string;
507
+ }
508
+ /**
509
+ * A document retrieved from a data source.
510
+ */
511
+ interface Document {
512
+ /** The document content */
513
+ content: string;
514
+ /** Relevance score (0-1) */
515
+ score: number;
516
+ /** Additional metadata */
517
+ metadata: Record<string, unknown>;
518
+ }
519
+ /**
520
+ * Status of a data source query.
521
+ */
522
+ type SourceStatus = 'success' | 'error' | 'timeout';
523
+ /**
524
+ * Information about a data source retrieval (metadata).
525
+ */
526
+ interface SourceInfo {
527
+ /** Endpoint path (owner/slug) */
528
+ path: string;
529
+ /** Number of documents retrieved from this source */
530
+ documentsRetrieved: number;
531
+ /** Query status */
532
+ status: SourceStatus;
533
+ /** Error message if status is error/timeout */
534
+ errorMessage?: string;
535
+ }
536
+ /**
537
+ * A document source entry with endpoint path and content.
538
+ * Used in the sources dict of ChatResponse, keyed by document title.
539
+ */
540
+ interface DocumentSource {
541
+ /** Endpoint path (owner/slug) where document was retrieved */
542
+ slug: string;
543
+ /** The actual document content */
544
+ content: string;
545
+ }
546
+ /**
547
+ * Timing metadata for chat response.
548
+ */
549
+ interface ChatMetadata {
550
+ /** Time spent retrieving documents (ms) */
551
+ retrievalTimeMs: number;
552
+ /** Time spent generating response (ms) */
553
+ generationTimeMs: number;
554
+ /** Total request time (ms) */
555
+ totalTimeMs: number;
556
+ }
557
+ /**
558
+ * Token usage information from model generation.
559
+ */
560
+ interface TokenUsage {
561
+ /** Number of tokens in the prompt */
562
+ promptTokens: number;
563
+ /** Number of tokens in the completion */
564
+ completionTokens: number;
565
+ /** Total tokens used */
566
+ totalTokens: number;
567
+ }
568
+ /**
569
+ * Response from a chat completion request.
570
+ */
571
+ interface ChatResponse {
572
+ /** The generated response text */
573
+ response: string;
574
+ /** Retrieved documents keyed by title, with endpoint slug and content */
575
+ sources: Record<string, DocumentSource>;
576
+ /** Metadata about each data source retrieval (status, count, errors) */
577
+ retrievalInfo: SourceInfo[];
578
+ /** Timing metadata */
579
+ metadata: ChatMetadata;
580
+ /** Token usage if available */
581
+ usage?: TokenUsage;
582
+ }
583
+ /**
584
+ * A chat message for model queries.
585
+ */
586
+ interface Message {
587
+ /** Message role (system, user, assistant) */
588
+ role: 'system' | 'user' | 'assistant';
589
+ /** Message content */
590
+ content: string;
591
+ }
592
+ /**
593
+ * Options for chat completion.
594
+ */
595
+ interface ChatOptions {
596
+ /** The user's question or prompt */
597
+ prompt: string;
598
+ /** Model endpoint (path string, EndpointRef, or EndpointPublic) */
599
+ model: string | EndpointRef;
600
+ /** Optional list of data source endpoints for context */
601
+ dataSources?: (string | EndpointRef)[];
602
+ /** Number of documents to retrieve per source (default: 5) */
603
+ topK?: number;
604
+ /** Maximum tokens to generate (default: 1024) */
605
+ maxTokens?: number;
606
+ /** Generation temperature (default: 0.7) */
607
+ temperature?: number;
608
+ /** Minimum similarity for retrieved docs (default: 0.5) */
609
+ similarityThreshold?: number;
610
+ /** AbortSignal for request cancellation */
611
+ signal?: AbortSignal;
612
+ }
613
+ /**
614
+ * Options for querying a data source directly.
615
+ */
616
+ interface QueryDataSourceOptions {
617
+ /** EndpointRef with URL and slug */
618
+ endpoint: EndpointRef;
619
+ /** The search query */
620
+ query: string;
621
+ /** User email for visibility/policy checks */
622
+ userEmail: string;
623
+ /** Number of documents to retrieve (default: 5) */
624
+ topK?: number;
625
+ /** Minimum similarity score (default: 0.5) */
626
+ similarityThreshold?: number;
627
+ }
628
+ /**
629
+ * Options for querying a model directly.
630
+ */
631
+ interface QueryModelOptions {
632
+ /** EndpointRef with URL and slug */
633
+ endpoint: EndpointRef;
634
+ /** List of chat messages */
635
+ messages: Message[];
636
+ /** User email for visibility/policy checks */
637
+ userEmail: string;
638
+ /** Maximum tokens to generate (default: 1024) */
639
+ maxTokens?: number;
640
+ /** Generation temperature (default: 0.7) */
641
+ temperature?: number;
642
+ }
643
+ /**
644
+ * Fired when retrieval begins.
645
+ */
646
+ interface RetrievalStartEvent {
647
+ type: 'retrieval_start';
648
+ sourceCount: number;
649
+ }
650
+ /**
651
+ * Fired when a single source finishes querying.
652
+ */
653
+ interface SourceCompleteEvent {
654
+ type: 'source_complete';
655
+ path: string;
656
+ status: string;
657
+ documentsRetrieved: number;
658
+ }
659
+ /**
660
+ * Fired when all retrieval is done.
661
+ */
662
+ interface RetrievalCompleteEvent {
663
+ type: 'retrieval_complete';
664
+ totalDocuments: number;
665
+ timeMs: number;
666
+ }
667
+ /**
668
+ * Fired when model generation begins.
669
+ */
670
+ interface GenerationStartEvent {
671
+ type: 'generation_start';
672
+ }
673
+ /**
674
+ * Fired for each token from the model.
675
+ */
676
+ interface TokenEvent {
677
+ type: 'token';
678
+ content: string;
679
+ }
680
+ /**
681
+ * Fired when generation completes successfully.
682
+ */
683
+ interface DoneEvent {
684
+ type: 'done';
685
+ /** Retrieved documents keyed by title, with endpoint slug and content */
686
+ sources: Record<string, DocumentSource>;
687
+ /** Metadata about each data source retrieval (status, count, errors) */
688
+ retrievalInfo: SourceInfo[];
689
+ metadata: ChatMetadata;
690
+ /** Token usage if available (only from non-streaming mode) */
691
+ usage?: TokenUsage;
692
+ }
693
+ /**
694
+ * Fired on error.
695
+ */
696
+ interface ErrorEvent {
697
+ type: 'error';
698
+ message: string;
699
+ }
700
+ /**
701
+ * Discriminated union of all streaming event types.
702
+ *
703
+ * Use type narrowing to handle each event type:
704
+ *
705
+ * @example
706
+ * for await (const event of client.chat.stream(options)) {
707
+ * switch (event.type) {
708
+ * case 'token':
709
+ * process.stdout.write(event.content);
710
+ * break;
711
+ * case 'done':
712
+ * console.log(`\nCompleted in ${event.metadata.totalTimeMs}ms`);
713
+ * break;
714
+ * case 'error':
715
+ * console.error(`Error: ${event.message}`);
716
+ * break;
717
+ * }
718
+ * }
719
+ */
720
+ type ChatStreamEvent = RetrievalStartEvent | SourceCompleteEvent | RetrievalCompleteEvent | GenerationStartEvent | TokenEvent | DoneEvent | ErrorEvent;
721
+
722
+ /**
723
+ * Authentication resource for login, register, and session management.
724
+ *
725
+ * @example
726
+ * // Register a new user
727
+ * const user = await client.auth.register({
728
+ * username: 'alice',
729
+ * email: 'alice@example.com',
730
+ * password: 'SecurePass123!',
731
+ * fullName: 'Alice'
732
+ * });
733
+ *
734
+ * @example
735
+ * // Login
736
+ * const user = await client.auth.login('alice', 'SecurePass123!');
737
+ *
738
+ * @example
739
+ * // Get current user
740
+ * const me = await client.auth.me();
741
+ *
742
+ * @example
743
+ * // Logout
744
+ * await client.auth.logout();
745
+ */
746
+ declare class AuthResource {
747
+ private readonly http;
748
+ constructor(http: HTTPClient);
749
+ /**
750
+ * Register a new user account.
751
+ *
752
+ * If an accounting service URL is configured (via `accountingServiceUrl` or server default),
753
+ * the backend will handle accounting integration using a "try-create-first" approach:
754
+ *
755
+ * **Accounting Password Behavior:**
756
+ * - **Not provided**: A secure password is auto-generated and a new accounting account is created.
757
+ * - **Provided (new user)**: The account is created with your chosen password.
758
+ * - **Provided (existing user)**: Your password is validated and accounts are linked.
759
+ *
760
+ * This means you can set your own accounting password during registration even if you're
761
+ * a new user - you don't need an existing accounting account first.
762
+ *
763
+ * @param input - Registration details (username, email, password, fullName)
764
+ * @returns The created User
765
+ * @throws {ValidationError} If input validation fails
766
+ * @throws {UserAlreadyExistsError} If username or email already exists in SyftHub
767
+ * @throws {AccountingAccountExistsError} If email already exists in accounting service
768
+ * and no `accountingPassword` was provided. Retry with the password.
769
+ * @throws {InvalidAccountingPasswordError} If the provided accounting password doesn't
770
+ * match an existing accounting account
771
+ * @throws {AccountingServiceUnavailableError} If the accounting service is unreachable
772
+ *
773
+ * @example
774
+ * // Basic registration (auto-generated accounting password)
775
+ * const user = await client.auth.register({
776
+ * username: 'alice',
777
+ * email: 'alice@example.com',
778
+ * password: 'SecurePass123!',
779
+ * fullName: 'Alice'
780
+ * });
781
+ *
782
+ * @example
783
+ * // Registration with custom accounting password (NEW user)
784
+ * const user = await client.auth.register({
785
+ * username: 'bob',
786
+ * email: 'bob@example.com',
787
+ * password: 'SecurePass123!',
788
+ * fullName: 'Bob',
789
+ * accountingPassword: 'MyChosenAccountingPass!' // Creates account with this password
790
+ * });
791
+ *
792
+ * @example
793
+ * // Handle existing accounting account
794
+ * try {
795
+ * await client.auth.register({ username, email, password, fullName });
796
+ * } catch (error) {
797
+ * if (error instanceof AccountingAccountExistsError) {
798
+ * // Prompt user for their existing accounting password
799
+ * const accountingPassword = await promptUser('Enter your existing accounting password:');
800
+ * await client.auth.register({ username, email, password, fullName, accountingPassword });
801
+ * } else {
802
+ * throw error;
803
+ * }
804
+ * }
805
+ */
806
+ register(input: UserRegisterInput): Promise<User>;
807
+ /**
808
+ * Login with username/email and password.
809
+ *
810
+ * Uses OAuth2 password flow (form-urlencoded body).
811
+ *
812
+ * @param username - Username or email
813
+ * @param password - Password
814
+ * @returns The authenticated User
815
+ * @throws {AuthenticationError} If credentials are invalid
816
+ */
817
+ login(username: string, password: string): Promise<User>;
818
+ /**
819
+ * Logout the current user.
820
+ *
821
+ * Invalidates tokens on the server and clears local token storage.
822
+ */
823
+ logout(): Promise<void>;
824
+ /**
825
+ * Get the current authenticated user.
826
+ *
827
+ * @returns The current User
828
+ * @throws {AuthenticationError} If not authenticated
829
+ */
830
+ me(): Promise<User>;
831
+ /**
832
+ * Manually refresh the access token.
833
+ *
834
+ * This is normally handled automatically when a request returns 401.
835
+ *
836
+ * @throws {AuthenticationError} If refresh token is invalid or expired
837
+ */
838
+ refresh(): Promise<void>;
839
+ /**
840
+ * Change the current user's password.
841
+ *
842
+ * @param currentPassword - Current password for verification
843
+ * @param newPassword - New password to set
844
+ * @throws {AuthenticationError} If current password is incorrect
845
+ * @throws {ValidationError} If new password doesn't meet requirements
846
+ */
847
+ changePassword(currentPassword: string, newPassword: string): Promise<void>;
848
+ /**
849
+ * Get a satellite token for a specific audience (target service).
850
+ *
851
+ * Satellite tokens are short-lived, RS256-signed JWTs that allow satellite
852
+ * services (like SyftAI-Space) to verify user identity without calling
853
+ * SyftHub for every request.
854
+ *
855
+ * @param audience - Target service identifier (username of the service owner)
856
+ * @returns Satellite token response with token and expiry
857
+ * @throws {AuthenticationError} If not authenticated
858
+ * @throws {ValidationError} If audience is invalid or inactive
859
+ *
860
+ * @example
861
+ * // Get a token for querying alice's SyftAI-Space endpoints
862
+ * const tokenResponse = await client.auth.getSatelliteToken('alice');
863
+ * console.log(`Token expires in ${tokenResponse.expiresIn} seconds`);
864
+ */
865
+ getSatelliteToken(audience: string): Promise<SatelliteTokenResponse>;
866
+ /**
867
+ * Get satellite tokens for multiple audiences in parallel.
868
+ *
869
+ * This is useful when making requests to endpoints owned by different users.
870
+ * Tokens are cached and reused where possible.
871
+ *
872
+ * @param audiences - Array of unique audience identifiers (usernames)
873
+ * @returns Map of audience to satellite token
874
+ * @throws {AuthenticationError} If not authenticated
875
+ *
876
+ * @example
877
+ * // Get tokens for multiple endpoint owners
878
+ * const tokens = await client.auth.getSatelliteTokens(['alice', 'bob']);
879
+ * console.log(`Got ${tokens.size} tokens`);
880
+ */
881
+ getSatelliteTokens(audiences: string[]): Promise<Map<string, string>>;
882
+ /**
883
+ * Get transaction tokens for multiple endpoint owners.
884
+ *
885
+ * Transaction tokens are short-lived JWTs that pre-authorize the endpoint owner
886
+ * (recipient) to charge the current user (sender) for usage. These tokens are
887
+ * created via the accounting service and passed to the aggregator.
888
+ *
889
+ * This is used by the chat flow to enable billing for endpoint usage.
890
+ *
891
+ * @param ownerUsernames - Array of endpoint owner usernames
892
+ * @returns TransactionTokensResponse with tokens map and any errors
893
+ * @throws {AuthenticationError} If not authenticated
894
+ *
895
+ * @example
896
+ * // Get transaction tokens for endpoint owners
897
+ * const response = await client.auth.getTransactionTokens(['alice', 'bob']);
898
+ * console.log(`Got ${Object.keys(response.tokens).length} tokens`);
899
+ * if (Object.keys(response.errors).length > 0) {
900
+ * console.log('Some tokens failed:', response.errors);
901
+ * }
902
+ */
903
+ getTransactionTokens(ownerUsernames: string[]): Promise<TransactionTokensResponse>;
904
+ }
905
+ /**
906
+ * Response from satellite token endpoint.
907
+ */
908
+ interface SatelliteTokenResponse {
909
+ /** RS256-signed JWT for the target service */
910
+ targetToken: string;
911
+ /** Seconds until the token expires */
912
+ expiresIn: number;
913
+ }
914
+ /**
915
+ * Response from transaction tokens endpoint.
916
+ */
917
+ interface TransactionTokensResponse {
918
+ /** Mapping of owner_username to transaction token */
919
+ tokens: Record<string, string>;
920
+ /** Mapping of owner_username to error message (for failed tokens) */
921
+ errors: Record<string, string>;
922
+ }
923
+
924
+ /**
925
+ * Users resource for profile management and availability checks.
926
+ *
927
+ * @example
928
+ * // Update your profile
929
+ * const user = await client.users.update({
930
+ * fullName: 'Alice Smith',
931
+ * avatarUrl: 'https://example.com/avatar.jpg'
932
+ * });
933
+ *
934
+ * @example
935
+ * // Check if username is available
936
+ * const available = await client.users.checkUsername('newusername');
937
+ *
938
+ * @example
939
+ * // Check if email is available
940
+ * const available = await client.users.checkEmail('new@example.com');
941
+ */
942
+ declare class UsersResource {
943
+ private readonly http;
944
+ constructor(http: HTTPClient);
945
+ /**
946
+ * Update the current user's profile.
947
+ *
948
+ * Only provided fields will be updated.
949
+ *
950
+ * @param input - Fields to update
951
+ * @returns The updated User
952
+ * @throws {AuthenticationError} If not authenticated
953
+ * @throws {ValidationError} If input validation fails
954
+ */
955
+ update(input: UserUpdateInput): Promise<User>;
956
+ /**
957
+ * Check if a username is available.
958
+ *
959
+ * @param username - Username to check
960
+ * @returns True if the username is available
961
+ */
962
+ checkUsername(username: string): Promise<boolean>;
963
+ /**
964
+ * Check if an email is available.
965
+ *
966
+ * @param email - Email to check
967
+ * @returns True if the email is available
968
+ */
969
+ checkEmail(email: string): Promise<boolean>;
970
+ /**
971
+ * Get the current user's accounting service credentials.
972
+ *
973
+ * Returns credentials stored in SyftHub for connecting to an external
974
+ * accounting service. The email is always the same as the user's SyftHub email.
975
+ *
976
+ * @returns Accounting credentials (url and password may be null if not configured)
977
+ * @throws {AuthenticationError} If not authenticated
978
+ *
979
+ * @example
980
+ * const credentials = await client.users.getAccountingCredentials();
981
+ * if (credentials.url && credentials.password) {
982
+ * // Use credentials to connect to accounting service
983
+ * }
984
+ */
985
+ getAccountingCredentials(): Promise<AccountingCredentials>;
986
+ }
987
+
988
+ /**
989
+ * Function type for fetching a page of items.
990
+ */
991
+ type PageFetcher<T> = (skip: number, limit: number) => Promise<T[]>;
992
+ /**
993
+ * Lazy async iterator for paginated API responses.
994
+ *
995
+ * Fetches pages on demand as you iterate, minimizing API calls
996
+ * and memory usage for large datasets.
997
+ *
998
+ * @example
999
+ * // Iterate through all items
1000
+ * for await (const endpoint of client.hub.browse()) {
1001
+ * console.log(endpoint.name);
1002
+ * }
1003
+ *
1004
+ * @example
1005
+ * // Get just the first page
1006
+ * const firstPage = await client.hub.browse().firstPage();
1007
+ *
1008
+ * @example
1009
+ * // Get first 10 items
1010
+ * const top10 = await client.hub.browse().take(10);
1011
+ */
1012
+ declare class PageIterator<T> implements AsyncIterable<T> {
1013
+ private readonly fetcher;
1014
+ private readonly pageSize;
1015
+ private items;
1016
+ private index;
1017
+ private skip;
1018
+ private exhausted;
1019
+ private initialized;
1020
+ /**
1021
+ * Create a new PageIterator.
1022
+ *
1023
+ * @param fetcher - Function that fetches a page of items given skip and limit
1024
+ * @param pageSize - Number of items to fetch per page (default: 20)
1025
+ */
1026
+ constructor(fetcher: PageFetcher<T>, pageSize?: number);
1027
+ /**
1028
+ * Async iterator implementation for `for await...of` loops.
1029
+ */
1030
+ [Symbol.asyncIterator](): AsyncIterator<T>;
1031
+ /**
1032
+ * Get just the first page of results.
1033
+ *
1034
+ * @returns Promise resolving to the first page of items
1035
+ */
1036
+ firstPage(): Promise<T[]>;
1037
+ /**
1038
+ * Get all items across all pages.
1039
+ *
1040
+ * Warning: This loads all items into memory. For large datasets,
1041
+ * consider iterating with `for await...of` instead.
1042
+ *
1043
+ * @returns Promise resolving to all items
1044
+ */
1045
+ all(): Promise<T[]>;
1046
+ /**
1047
+ * Get the first N items.
1048
+ *
1049
+ * @param n - Maximum number of items to return
1050
+ * @returns Promise resolving to up to N items
1051
+ */
1052
+ take(n: number): Promise<T[]>;
1053
+ /**
1054
+ * Fetch the next page of items from the API.
1055
+ */
1056
+ private fetchNextPage;
1057
+ }
1058
+
1059
+ /**
1060
+ * Options for listing endpoints.
1061
+ */
1062
+ interface ListEndpointsOptions {
1063
+ /** Filter by visibility level */
1064
+ visibility?: Visibility;
1065
+ /** Number of items per page (default: 20) */
1066
+ pageSize?: number;
1067
+ }
1068
+ /**
1069
+ * My Endpoints resource for CRUD operations on user's own endpoints.
1070
+ *
1071
+ * For browsing public endpoints from other users, see the Hub resource.
1072
+ *
1073
+ * @example
1074
+ * // List your endpoints
1075
+ * for await (const endpoint of client.myEndpoints.list()) {
1076
+ * console.log(endpoint.name);
1077
+ * }
1078
+ *
1079
+ * @example
1080
+ * // Create a new endpoint
1081
+ * const endpoint = await client.myEndpoints.create({
1082
+ * name: 'My API',
1083
+ * type: 'model',
1084
+ * visibility: 'public',
1085
+ * description: 'A cool API'
1086
+ * });
1087
+ *
1088
+ * @example
1089
+ * // Get a specific endpoint
1090
+ * const endpoint = await client.myEndpoints.get('alice/my-api');
1091
+ *
1092
+ * @example
1093
+ * // Update an endpoint
1094
+ * const updated = await client.myEndpoints.update('alice/my-api', {
1095
+ * description: 'Updated description'
1096
+ * });
1097
+ *
1098
+ * @example
1099
+ * // Delete an endpoint
1100
+ * await client.myEndpoints.delete('alice/my-api');
1101
+ */
1102
+ declare class MyEndpointsResource {
1103
+ private readonly http;
1104
+ constructor(http: HTTPClient);
1105
+ /**
1106
+ * Parse an endpoint path into owner and slug.
1107
+ *
1108
+ * @param path - Path in "owner/slug" format
1109
+ * @returns Tuple of [owner, slug]
1110
+ * @throws {Error} If path format is invalid
1111
+ */
1112
+ private parsePath;
1113
+ /**
1114
+ * Resolve an endpoint path to its ID.
1115
+ *
1116
+ * @param path - Endpoint path in "owner/slug" format
1117
+ * @returns The endpoint ID
1118
+ */
1119
+ private resolveEndpointId;
1120
+ /**
1121
+ * List the current user's endpoints.
1122
+ *
1123
+ * @param options - Filtering and pagination options
1124
+ * @returns PageIterator that lazily fetches endpoints
1125
+ * @throws {AuthenticationError} If not authenticated
1126
+ */
1127
+ list(options?: ListEndpointsOptions): PageIterator<Endpoint>;
1128
+ /**
1129
+ * Create a new endpoint.
1130
+ *
1131
+ * @param input - Endpoint creation details
1132
+ * @param organizationId - Optional organization ID (for org-owned endpoints)
1133
+ * @returns The created Endpoint
1134
+ * @throws {AuthenticationError} If not authenticated
1135
+ * @throws {ValidationError} If input validation fails
1136
+ */
1137
+ create(input: EndpointCreateInput, organizationId?: number): Promise<Endpoint>;
1138
+ /**
1139
+ * Get a specific endpoint by path.
1140
+ *
1141
+ * @param path - Endpoint path in "owner/slug" format (e.g., "alice/my-api")
1142
+ * @returns The Endpoint
1143
+ * @throws {AuthenticationError} If not authenticated
1144
+ * @throws {NotFoundError} If endpoint not found
1145
+ * @throws {AuthorizationError} If not authorized to view
1146
+ */
1147
+ get(path: string): Promise<Endpoint>;
1148
+ /**
1149
+ * Update an endpoint.
1150
+ *
1151
+ * Only provided fields will be updated.
1152
+ *
1153
+ * @param path - Endpoint path in "owner/slug" format
1154
+ * @param input - Fields to update
1155
+ * @returns The updated Endpoint
1156
+ * @throws {AuthenticationError} If not authenticated
1157
+ * @throws {NotFoundError} If endpoint not found
1158
+ * @throws {AuthorizationError} If not owner/admin
1159
+ */
1160
+ update(path: string, input: EndpointUpdateInput): Promise<Endpoint>;
1161
+ /**
1162
+ * Delete an endpoint.
1163
+ *
1164
+ * @param path - Endpoint path in "owner/slug" format
1165
+ * @throws {AuthenticationError} If not authenticated
1166
+ * @throws {NotFoundError} If endpoint not found
1167
+ * @throws {AuthorizationError} If not owner/admin
1168
+ */
1169
+ delete(path: string): Promise<void>;
1170
+ }
1171
+
1172
+ /**
1173
+ * Options for browsing endpoints.
1174
+ */
1175
+ interface BrowseOptions {
1176
+ /** Number of items per page (default: 20) */
1177
+ pageSize?: number;
1178
+ }
1179
+ /**
1180
+ * Options for trending endpoints.
1181
+ */
1182
+ interface TrendingOptions {
1183
+ /** Minimum number of stars */
1184
+ minStars?: number;
1185
+ /** Number of items per page (default: 20) */
1186
+ pageSize?: number;
1187
+ }
1188
+ /**
1189
+ * Hub resource for browsing and discovering public endpoints.
1190
+ *
1191
+ * For managing your own endpoints, see the MyEndpoints resource.
1192
+ *
1193
+ * @example
1194
+ * // Browse all public endpoints
1195
+ * for await (const endpoint of client.hub.browse()) {
1196
+ * console.log(`${endpoint.ownerUsername}/${endpoint.slug}: ${endpoint.name}`);
1197
+ * }
1198
+ *
1199
+ * @example
1200
+ * // Get trending endpoints
1201
+ * for await (const endpoint of client.hub.trending({ minStars: 10 })) {
1202
+ * console.log(`${endpoint.name} - ${endpoint.starsCount} stars`);
1203
+ * }
1204
+ *
1205
+ * @example
1206
+ * // Get a specific endpoint
1207
+ * const endpoint = await client.hub.get('alice/cool-api');
1208
+ * console.log(endpoint.readme);
1209
+ *
1210
+ * @example
1211
+ * // Star an endpoint (requires auth)
1212
+ * await client.hub.star('alice/cool-api');
1213
+ *
1214
+ * @example
1215
+ * // Check if you've starred an endpoint
1216
+ * const starred = await client.hub.isStarred('alice/cool-api');
1217
+ */
1218
+ declare class HubResource {
1219
+ private readonly http;
1220
+ constructor(http: HTTPClient);
1221
+ /**
1222
+ * Parse an endpoint path into owner and slug.
1223
+ *
1224
+ * @param path - Path in "owner/slug" format
1225
+ * @returns Tuple of [owner, slug]
1226
+ */
1227
+ private parsePath;
1228
+ /**
1229
+ * Resolve an endpoint path to its ID.
1230
+ *
1231
+ * This searches the user's own endpoints to find the ID.
1232
+ *
1233
+ * @param path - Endpoint path in "owner/slug" format
1234
+ * @returns The endpoint ID
1235
+ */
1236
+ private resolveEndpointId;
1237
+ /**
1238
+ * Browse all public endpoints.
1239
+ *
1240
+ * @param options - Pagination options
1241
+ * @returns PageIterator that lazily fetches endpoints
1242
+ */
1243
+ browse(options?: BrowseOptions): PageIterator<EndpointPublic>;
1244
+ /**
1245
+ * Get trending endpoints sorted by stars.
1246
+ *
1247
+ * @param options - Filter and pagination options
1248
+ * @returns PageIterator that lazily fetches endpoints
1249
+ */
1250
+ trending(options?: TrendingOptions): PageIterator<EndpointPublic>;
1251
+ /**
1252
+ * Get an endpoint by its path.
1253
+ *
1254
+ * This method searches the public endpoints API to find the endpoint,
1255
+ * which works reliably across all deployment configurations.
1256
+ *
1257
+ * @param path - Endpoint path in "owner/slug" format (e.g., "alice/cool-api")
1258
+ * @returns The EndpointPublic
1259
+ * @throws {NotFoundError} If endpoint not found
1260
+ */
1261
+ get(path: string): Promise<EndpointPublic>;
1262
+ /**
1263
+ * Star an endpoint.
1264
+ *
1265
+ * @param path - Endpoint path in "owner/slug" format
1266
+ * @throws {AuthenticationError} If not authenticated
1267
+ * @throws {NotFoundError} If endpoint not found
1268
+ */
1269
+ star(path: string): Promise<void>;
1270
+ /**
1271
+ * Unstar an endpoint.
1272
+ *
1273
+ * @param path - Endpoint path in "owner/slug" format
1274
+ * @throws {AuthenticationError} If not authenticated
1275
+ * @throws {NotFoundError} If endpoint not found
1276
+ */
1277
+ unstar(path: string): Promise<void>;
1278
+ /**
1279
+ * Check if you have starred an endpoint.
1280
+ *
1281
+ * @param path - Endpoint path in "owner/slug" format
1282
+ * @returns True if starred, False otherwise
1283
+ * @throws {AuthenticationError} If not authenticated
1284
+ * @throws {NotFoundError} If endpoint not found
1285
+ */
1286
+ isStarred(path: string): Promise<boolean>;
1287
+ }
1288
+
1289
+ /**
1290
+ * Accounting Resource for SyftHub SDK
1291
+ *
1292
+ * This module connects to an external accounting/billing service for managing
1293
+ * user balances and transactions. The accounting service is separate from SyftHub
1294
+ * and uses its own authentication (Basic auth with email/password).
1295
+ *
1296
+ * @example
1297
+ * ```typescript
1298
+ * // Create accounting client
1299
+ * const accounting = new AccountingResource({
1300
+ * url: 'https://accounting.example.com',
1301
+ * email: 'user@example.com',
1302
+ * password: 'secret'
1303
+ * });
1304
+ *
1305
+ * // Get user balance
1306
+ * const user = await accounting.getUser();
1307
+ * console.log(`Balance: ${user.balance}`);
1308
+ *
1309
+ * // Create a transaction
1310
+ * const tx = await accounting.createTransaction({
1311
+ * recipientEmail: 'recipient@example.com',
1312
+ * amount: 10.0,
1313
+ * appName: 'syftai-space',
1314
+ * appEpPath: 'alice/my-model'
1315
+ * });
1316
+ *
1317
+ * // Confirm the transaction
1318
+ * await accounting.confirmTransaction(tx.id);
1319
+ * ```
1320
+ */
1321
+
1322
+ /**
1323
+ * Options for creating an AccountingResource.
1324
+ */
1325
+ interface AccountingResourceOptions {
1326
+ /** Accounting service URL */
1327
+ url: string;
1328
+ /** Email for Basic auth */
1329
+ email: string;
1330
+ /** Password for Basic auth */
1331
+ password: string;
1332
+ /** Request timeout in milliseconds (default: 30000) */
1333
+ timeout?: number;
1334
+ }
1335
+ /**
1336
+ * Options for listing transactions.
1337
+ */
1338
+ interface TransactionsOptions {
1339
+ /** Number of items per page (default: 20) */
1340
+ pageSize?: number;
1341
+ }
1342
+ /**
1343
+ * Handle accounting/billing operations with external service.
1344
+ *
1345
+ * The accounting service manages user balances and transactions. It uses
1346
+ * Basic auth (email/password) for authentication, which is separate from
1347
+ * SyftHub's JWT-based authentication.
1348
+ *
1349
+ * Transaction Workflow:
1350
+ * 1. Sender creates transaction (status=PENDING)
1351
+ * 2. Either party confirms (status=COMPLETED) or cancels (status=CANCELLED)
1352
+ *
1353
+ * Delegated Transaction Workflow:
1354
+ * 1. Sender creates a transaction token for recipient
1355
+ * 2. Recipient uses token to create delegated transaction
1356
+ * 3. Recipient confirms the transaction
1357
+ */
1358
+ declare class AccountingResource {
1359
+ private readonly baseUrl;
1360
+ private readonly email;
1361
+ private readonly password;
1362
+ private readonly timeout;
1363
+ private readonly authHeader;
1364
+ constructor(options: AccountingResourceOptions);
1365
+ /**
1366
+ * Make an authenticated request to the accounting service.
1367
+ */
1368
+ private request;
1369
+ /**
1370
+ * Make a request using Bearer token auth (for delegated transactions).
1371
+ */
1372
+ private requestWithToken;
1373
+ /**
1374
+ * Get the current user's account information including balance.
1375
+ *
1376
+ * @returns AccountingUser with id, email, balance, and organization
1377
+ * @throws {AuthenticationError} If authentication fails
1378
+ * @throws {APIError} On other errors
1379
+ *
1380
+ * @example
1381
+ * ```typescript
1382
+ * const user = await accounting.getUser();
1383
+ * console.log(`Balance: ${user.balance}`);
1384
+ * console.log(`Organization: ${user.organization}`);
1385
+ * ```
1386
+ */
1387
+ getUser(): Promise<AccountingUser>;
1388
+ /**
1389
+ * Update the user's password.
1390
+ *
1391
+ * @param currentPassword - Current password for verification
1392
+ * @param newPassword - New password to set
1393
+ * @throws {AuthenticationError} If current password is wrong
1394
+ * @throws {ValidationError} If new password doesn't meet requirements
1395
+ *
1396
+ * @example
1397
+ * ```typescript
1398
+ * await accounting.updatePassword('old_secret', 'new_secret');
1399
+ * ```
1400
+ */
1401
+ updatePassword(currentPassword: string, newPassword: string): Promise<void>;
1402
+ /**
1403
+ * Update the user's organization.
1404
+ *
1405
+ * @param organization - New organization name
1406
+ * @throws {AuthenticationError} If authentication fails
1407
+ *
1408
+ * @example
1409
+ * ```typescript
1410
+ * await accounting.updateOrganization('OpenMined');
1411
+ * ```
1412
+ */
1413
+ updateOrganization(organization: string): Promise<void>;
1414
+ /**
1415
+ * List account transactions with pagination.
1416
+ *
1417
+ * Returns a lazy iterator that fetches pages on demand.
1418
+ *
1419
+ * @param options - Pagination options
1420
+ * @returns PageIterator that yields Transaction objects
1421
+ *
1422
+ * @example
1423
+ * ```typescript
1424
+ * // Iterate through all transactions
1425
+ * for await (const tx of accounting.getTransactions()) {
1426
+ * console.log(`${tx.createdAt}: ${tx.amount} from ${tx.senderEmail}`);
1427
+ * }
1428
+ *
1429
+ * // Get first page only
1430
+ * const firstPage = await accounting.getTransactions().firstPage();
1431
+ *
1432
+ * // Get all transactions
1433
+ * const allTxs = await accounting.getTransactions().all();
1434
+ * ```
1435
+ */
1436
+ getTransactions(options?: TransactionsOptions): PageIterator<Transaction>;
1437
+ /**
1438
+ * Get a specific transaction by ID.
1439
+ *
1440
+ * @param transactionId - The transaction ID
1441
+ * @returns Transaction object
1442
+ * @throws {NotFoundError} If transaction not found
1443
+ *
1444
+ * @example
1445
+ * ```typescript
1446
+ * const tx = await accounting.getTransaction('tx_123');
1447
+ * console.log(`Status: ${tx.status}`);
1448
+ * ```
1449
+ */
1450
+ getTransaction(transactionId: string): Promise<Transaction>;
1451
+ /**
1452
+ * Create a new transaction (direct transfer).
1453
+ *
1454
+ * Creates a PENDING transaction that must be confirmed or cancelled.
1455
+ * The transaction is created by the sender (current user).
1456
+ *
1457
+ * @param input - Transaction details
1458
+ * @returns Transaction in PENDING status
1459
+ * @throws {ValidationError} If amount <= 0 or insufficient balance
1460
+ *
1461
+ * @example
1462
+ * ```typescript
1463
+ * const tx = await accounting.createTransaction({
1464
+ * recipientEmail: 'bob@example.com',
1465
+ * amount: 10.0,
1466
+ * appName: 'syftai-space',
1467
+ * appEpPath: 'alice/my-model'
1468
+ * });
1469
+ * console.log(`Created transaction ${tx.id}: ${tx.status}`);
1470
+ *
1471
+ * // Later, confirm or cancel
1472
+ * await accounting.confirmTransaction(tx.id);
1473
+ * ```
1474
+ */
1475
+ createTransaction(input: CreateTransactionInput): Promise<Transaction>;
1476
+ /**
1477
+ * Confirm a pending transaction.
1478
+ *
1479
+ * Confirms the transaction, transferring funds from sender to recipient.
1480
+ * Can be called by either the sender or recipient.
1481
+ *
1482
+ * @param transactionId - The transaction ID to confirm
1483
+ * @returns Transaction in COMPLETED status
1484
+ * @throws {NotFoundError} If transaction not found
1485
+ * @throws {ValidationError} If transaction is not in PENDING status
1486
+ *
1487
+ * @example
1488
+ * ```typescript
1489
+ * const tx = await accounting.confirmTransaction('tx_123');
1490
+ * console.log(`Confirmed: ${tx.status}`); // "completed"
1491
+ * ```
1492
+ */
1493
+ confirmTransaction(transactionId: string): Promise<Transaction>;
1494
+ /**
1495
+ * Cancel a pending transaction.
1496
+ *
1497
+ * Cancels the transaction without transferring funds.
1498
+ * Can be called by either the sender or recipient.
1499
+ *
1500
+ * @param transactionId - The transaction ID to cancel
1501
+ * @returns Transaction in CANCELLED status
1502
+ * @throws {NotFoundError} If transaction not found
1503
+ * @throws {ValidationError} If transaction is not in PENDING status
1504
+ *
1505
+ * @example
1506
+ * ```typescript
1507
+ * const tx = await accounting.cancelTransaction('tx_123');
1508
+ * console.log(`Cancelled: ${tx.status}`); // "cancelled"
1509
+ * ```
1510
+ */
1511
+ cancelTransaction(transactionId: string): Promise<Transaction>;
1512
+ /**
1513
+ * Create a transaction token for delegated transfers.
1514
+ *
1515
+ * Creates a JWT token that authorizes the recipient to create a
1516
+ * transaction on behalf of the sender (current user). The token
1517
+ * is short-lived (typically ~5 minutes).
1518
+ *
1519
+ * Use this when you want to pre-authorize a payment that will be
1520
+ * initiated by the recipient (e.g., a service charging for usage).
1521
+ *
1522
+ * @param recipientEmail - Email of the authorized recipient
1523
+ * @returns JWT token string to share with recipient
1524
+ *
1525
+ * @example
1526
+ * ```typescript
1527
+ * // Sender creates token
1528
+ * const token = await accounting.createTransactionToken('service@example.com');
1529
+ *
1530
+ * // Share token with recipient out-of-band
1531
+ * // Recipient uses token to create delegated transaction
1532
+ * ```
1533
+ */
1534
+ createTransactionToken(recipientEmail: string): Promise<string>;
1535
+ /**
1536
+ * Create a delegated transaction using a pre-authorized token.
1537
+ *
1538
+ * Creates a transaction on behalf of the sender using their token.
1539
+ * This is typically used by services to charge users for usage.
1540
+ *
1541
+ * The token authenticates the request instead of Basic auth.
1542
+ *
1543
+ * @param senderEmail - Email of the sender who created the token
1544
+ * @param amount - Amount to transfer (must be > 0)
1545
+ * @param token - JWT token from sender's createTransactionToken()
1546
+ * @returns Transaction in PENDING status (createdBy=RECIPIENT)
1547
+ * @throws {AuthenticationError} If token is invalid or expired
1548
+ * @throws {ValidationError} If amount <= 0
1549
+ *
1550
+ * @example
1551
+ * ```typescript
1552
+ * // Recipient creates transaction using sender's token
1553
+ * const tx = await accounting.createDelegatedTransaction(
1554
+ * 'alice@example.com',
1555
+ * 5.0,
1556
+ * aliceToken
1557
+ * );
1558
+ *
1559
+ * // Recipient confirms the transaction
1560
+ * await accounting.confirmTransaction(tx.id);
1561
+ * ```
1562
+ */
1563
+ createDelegatedTransaction(senderEmail: string, amount: number, token: string): Promise<Transaction>;
1564
+ }
1565
+ /**
1566
+ * Create a new AccountingResource instance.
1567
+ *
1568
+ * @param options - Configuration options
1569
+ * @returns AccountingResource instance
1570
+ *
1571
+ * @example
1572
+ * ```typescript
1573
+ * const accounting = createAccountingResource({
1574
+ * url: process.env.ACCOUNTING_URL!,
1575
+ * email: process.env.ACCOUNTING_EMAIL!,
1576
+ * password: process.env.ACCOUNTING_PASSWORD!
1577
+ * });
1578
+ * ```
1579
+ */
1580
+ declare function createAccountingResource(options: AccountingResourceOptions): AccountingResource;
1581
+
1582
+ /**
1583
+ * Base error class for all SyftHub SDK errors.
1584
+ */
1585
+ declare class SyftHubError extends Error {
1586
+ constructor(message: string);
1587
+ }
1588
+ /**
1589
+ * Error thrown when an API request fails with an error status code.
1590
+ */
1591
+ declare class APIError extends SyftHubError {
1592
+ readonly status: number;
1593
+ readonly data?: unknown | undefined;
1594
+ constructor(message: string, status: number, data?: unknown | undefined);
1595
+ }
1596
+ /**
1597
+ * Error thrown when authentication is required but not provided,
1598
+ * or when credentials are invalid (HTTP 401).
1599
+ */
1600
+ declare class AuthenticationError extends SyftHubError {
1601
+ constructor(message?: string);
1602
+ }
1603
+ /**
1604
+ * Error thrown when the user doesn't have permission to access
1605
+ * a resource (HTTP 403).
1606
+ */
1607
+ declare class AuthorizationError extends SyftHubError {
1608
+ constructor(message?: string);
1609
+ }
1610
+ /**
1611
+ * Error thrown when a requested resource is not found (HTTP 404).
1612
+ */
1613
+ declare class NotFoundError extends SyftHubError {
1614
+ constructor(message?: string);
1615
+ }
1616
+ /**
1617
+ * Error thrown when request validation fails (HTTP 422).
1618
+ * Contains field-level error details when available.
1619
+ */
1620
+ declare class ValidationError extends SyftHubError {
1621
+ readonly errors?: Record<string, string[]> | undefined;
1622
+ constructor(message: string, errors?: Record<string, string[]> | undefined);
1623
+ }
1624
+ /**
1625
+ * Error thrown when a network request fails (connection errors, timeouts).
1626
+ */
1627
+ declare class NetworkError extends SyftHubError {
1628
+ readonly cause?: Error | undefined;
1629
+ constructor(message?: string, cause?: Error | undefined);
1630
+ }
1631
+ /**
1632
+ * Error thrown when SDK configuration is invalid.
1633
+ */
1634
+ declare class ConfigurationError extends SyftHubError {
1635
+ constructor(message?: string);
1636
+ }
1637
+ /**
1638
+ * Error thrown when username or email already exists in SyftHub (HTTP 409).
1639
+ *
1640
+ * This error indicates a duplicate user registration attempt.
1641
+ * The `field` property indicates which field caused the conflict.
1642
+ *
1643
+ * @example
1644
+ * ```typescript
1645
+ * try {
1646
+ * await client.auth.register({ username: "john", email: "john@example.com", ... });
1647
+ * } catch (error) {
1648
+ * if (error instanceof UserAlreadyExistsError) {
1649
+ * console.log(`${error.field} is already taken`);
1650
+ * }
1651
+ * }
1652
+ * ```
1653
+ */
1654
+ declare class UserAlreadyExistsError extends SyftHubError {
1655
+ readonly detail?: unknown | undefined;
1656
+ /** The field that caused the conflict ("username" or "email") */
1657
+ readonly field?: string;
1658
+ constructor(message?: string, detail?: unknown | undefined);
1659
+ }
1660
+ /**
1661
+ * Error thrown when email already exists in the accounting service during registration.
1662
+ *
1663
+ * This error indicates that the user needs to provide their existing
1664
+ * accounting password to link their SyftHub account with their existing
1665
+ * accounting account.
1666
+ *
1667
+ * @example
1668
+ * ```typescript
1669
+ * try {
1670
+ * await client.auth.register({ username: "john", email: "john@example.com", ... });
1671
+ * } catch (error) {
1672
+ * if (error instanceof AccountingAccountExistsError) {
1673
+ * // Prompt user for their existing accounting password
1674
+ * const accountingPassword = prompt("Enter your existing accounting password:");
1675
+ * // Retry registration with the password
1676
+ * await client.auth.register({
1677
+ * username: "john",
1678
+ * email: "john@example.com",
1679
+ * ...,
1680
+ * accountingPassword
1681
+ * });
1682
+ * }
1683
+ * }
1684
+ * ```
1685
+ */
1686
+ declare class AccountingAccountExistsError extends SyftHubError {
1687
+ readonly detail?: unknown | undefined;
1688
+ /** Indicates that the user needs to provide their existing accounting password */
1689
+ readonly requiresAccountingPassword = true;
1690
+ constructor(message?: string, detail?: unknown | undefined);
1691
+ }
1692
+ /**
1693
+ * Error thrown when the provided accounting password is invalid.
1694
+ */
1695
+ declare class InvalidAccountingPasswordError extends SyftHubError {
1696
+ readonly detail?: unknown | undefined;
1697
+ constructor(message?: string, detail?: unknown | undefined);
1698
+ }
1699
+ /**
1700
+ * Error thrown when the accounting service is unavailable or returns an error.
1701
+ */
1702
+ declare class AccountingServiceUnavailableError extends SyftHubError {
1703
+ readonly detail?: unknown | undefined;
1704
+ constructor(message?: string, detail?: unknown | undefined);
1705
+ }
1706
+
1707
+ /**
1708
+ * Chat resource for RAG-augmented conversations via the Aggregator service.
1709
+ *
1710
+ * This resource handles satellite token authentication automatically:
1711
+ * - Resolves endpoints and extracts owner information
1712
+ * - Exchanges Hub access tokens for satellite tokens (one per unique owner)
1713
+ * - Sends tokens to the aggregator for forwarding to SyftAI-Space
1714
+ *
1715
+ * @example
1716
+ * // Simple chat completion
1717
+ * const response = await client.chat.complete({
1718
+ * prompt: 'What is machine learning?',
1719
+ * model: 'alice/gpt-model',
1720
+ * dataSources: ['bob/ml-docs'],
1721
+ * });
1722
+ * console.log(response.response);
1723
+ *
1724
+ * // Streaming chat
1725
+ * for await (const event of client.chat.stream(options)) {
1726
+ * if (event.type === 'token') {
1727
+ * process.stdout.write(event.content);
1728
+ * }
1729
+ * }
1730
+ */
1731
+
1732
+ /**
1733
+ * Error thrown when the aggregator service is unavailable or returns an error.
1734
+ */
1735
+ declare class AggregatorError extends SyftHubError {
1736
+ readonly status?: number | undefined;
1737
+ readonly detail?: unknown | undefined;
1738
+ constructor(message: string, status?: number | undefined, detail?: unknown | undefined);
1739
+ }
1740
+ /**
1741
+ * Error thrown when an endpoint cannot be resolved.
1742
+ */
1743
+ declare class EndpointResolutionError extends SyftHubError {
1744
+ readonly endpointPath?: string | undefined;
1745
+ constructor(message: string, endpointPath?: string | undefined);
1746
+ }
1747
+ /**
1748
+ * Chat resource for RAG-augmented conversations via the Aggregator.
1749
+ *
1750
+ * This resource provides high-level chat functionality that:
1751
+ * - Queries data sources for relevant context (retrieval)
1752
+ * - Sends prompts with context to model endpoints (generation)
1753
+ * - Supports both synchronous and streaming responses
1754
+ */
1755
+ declare class ChatResource {
1756
+ private readonly hub;
1757
+ private readonly auth;
1758
+ private readonly aggregatorUrl;
1759
+ constructor(hub: HubResource, auth: AuthResource, aggregatorUrl: string);
1760
+ /**
1761
+ * Convert any endpoint format to EndpointRef with URL and owner info.
1762
+ * The ownerUsername is critical for satellite token authentication.
1763
+ */
1764
+ private resolveEndpointRef;
1765
+ /**
1766
+ * Collect unique owner usernames from all endpoints.
1767
+ * Used to determine which satellite tokens need to be fetched.
1768
+ */
1769
+ private collectUniqueOwners;
1770
+ /**
1771
+ * Get satellite tokens for all unique endpoint owners.
1772
+ * Returns a map of owner username to satellite token.
1773
+ */
1774
+ private getSatelliteTokensForOwners;
1775
+ /**
1776
+ * Get transaction tokens for all unique endpoint owners.
1777
+ * Returns a map of owner username to transaction token.
1778
+ *
1779
+ * Transaction tokens are used for billing - they authorize the endpoint
1780
+ * owner to charge the current user for usage.
1781
+ */
1782
+ private getTransactionTokensForOwners;
1783
+ /**
1784
+ * Type guard for EndpointRef.
1785
+ */
1786
+ private isEndpointRef;
1787
+ /**
1788
+ * Type guard for EndpointPublic.
1789
+ */
1790
+ private isEndpointPublic;
1791
+ /**
1792
+ * Build the request body for the aggregator.
1793
+ * Includes endpoint_tokens mapping for satellite token authentication.
1794
+ * Includes transaction_tokens mapping for billing authorization.
1795
+ * User identity is derived from satellite tokens, not passed in request body.
1796
+ */
1797
+ private buildRequestBody;
1798
+ /**
1799
+ * Parse a SourceInfo from raw data.
1800
+ */
1801
+ private parseSourceInfo;
1802
+ /**
1803
+ * Parse ChatMetadata from raw data.
1804
+ */
1805
+ private parseMetadata;
1806
+ /**
1807
+ * Parse TokenUsage from raw data.
1808
+ */
1809
+ private parseUsage;
1810
+ /**
1811
+ * Parse document sources from raw data.
1812
+ * The new format is a dict mapping document title to {slug, content}.
1813
+ */
1814
+ private parseDocumentSources;
1815
+ /**
1816
+ * Parse retrieval info (SourceInfo array) from raw data.
1817
+ */
1818
+ private parseRetrievalInfo;
1819
+ /**
1820
+ * Send a chat request and get the complete response.
1821
+ *
1822
+ * This method automatically:
1823
+ * 1. Resolves endpoints and extracts owner information
1824
+ * 2. Exchanges Hub tokens for satellite tokens (one per unique owner)
1825
+ * 3. Fetches transaction tokens for billing authorization
1826
+ * 4. Sends tokens to the aggregator for forwarding to SyftAI-Space
1827
+ *
1828
+ * @param options - Chat completion options
1829
+ * @returns ChatResponse with response text, sources, and metadata
1830
+ * @throws {EndpointResolutionError} If endpoint cannot be resolved
1831
+ * @throws {AggregatorError} If aggregator service fails
1832
+ */
1833
+ complete(options: ChatOptions): Promise<ChatResponse>;
1834
+ /**
1835
+ * Send a chat request and stream response events.
1836
+ *
1837
+ * This method automatically:
1838
+ * 1. Resolves endpoints and extracts owner information
1839
+ * 2. Exchanges Hub tokens for satellite tokens (one per unique owner)
1840
+ * 3. Fetches transaction tokens for billing authorization
1841
+ * 4. Sends tokens to the aggregator for forwarding to SyftAI-Space
1842
+ *
1843
+ * @param options - Chat completion options
1844
+ * @yields ChatStreamEvent objects as they arrive
1845
+ */
1846
+ stream(options: ChatOptions): AsyncGenerator<ChatStreamEvent, void, unknown>;
1847
+ /**
1848
+ * Parse an SSE event into a typed event object.
1849
+ */
1850
+ private parseSSEEvent;
1851
+ /**
1852
+ * Get model endpoints that have connection URLs configured.
1853
+ *
1854
+ * @param limit - Maximum number of results (default: 20)
1855
+ * @returns Array of EndpointPublic objects for models with URLs
1856
+ */
1857
+ getAvailableModels(limit?: number): Promise<EndpointPublic[]>;
1858
+ /**
1859
+ * Get data source endpoints that have connection URLs configured.
1860
+ *
1861
+ * @param limit - Maximum number of results (default: 20)
1862
+ * @returns Array of EndpointPublic objects for data sources with URLs
1863
+ */
1864
+ getAvailableDataSources(limit?: number): Promise<EndpointPublic[]>;
1865
+ }
1866
+
1867
+ /**
1868
+ * SyftAI-Space resource for direct endpoint queries.
1869
+ *
1870
+ * This module provides low-level access to SyftAI-Space endpoints, allowing
1871
+ * users to build custom RAG pipelines or bypass the aggregator service.
1872
+ *
1873
+ * @example
1874
+ * // Query a data source directly
1875
+ * const docs = await client.syftai.queryDataSource({
1876
+ * endpoint: { url: 'http://syftai:8080', slug: 'docs' },
1877
+ * query: 'What is machine learning?',
1878
+ * userEmail: 'alice@example.com',
1879
+ * });
1880
+ *
1881
+ * // Query a model directly
1882
+ * const response = await client.syftai.queryModel({
1883
+ * endpoint: { url: 'http://syftai:8080', slug: 'gpt-model' },
1884
+ * messages: [
1885
+ * { role: 'system', content: 'You are a helpful assistant.' },
1886
+ * { role: 'user', content: 'Hello!' },
1887
+ * ],
1888
+ * userEmail: 'alice@example.com',
1889
+ * });
1890
+ */
1891
+
1892
+ /**
1893
+ * Error thrown when data source retrieval fails.
1894
+ */
1895
+ declare class RetrievalError extends SyftHubError {
1896
+ readonly sourcePath?: string | undefined;
1897
+ readonly detail?: unknown | undefined;
1898
+ constructor(message: string, sourcePath?: string | undefined, detail?: unknown | undefined);
1899
+ }
1900
+ /**
1901
+ * Error thrown when model generation fails.
1902
+ */
1903
+ declare class GenerationError extends SyftHubError {
1904
+ readonly modelSlug?: string | undefined;
1905
+ readonly detail?: unknown | undefined;
1906
+ constructor(message: string, modelSlug?: string | undefined, detail?: unknown | undefined);
1907
+ }
1908
+ /**
1909
+ * Low-level resource for direct SyftAI-Space endpoint queries.
1910
+ *
1911
+ * This resource provides direct access to SyftAI-Space endpoints without
1912
+ * going through the aggregator. Use this when you need:
1913
+ * - Custom RAG pipelines with specific retrieval strategies
1914
+ * - Direct model queries without data source context
1915
+ * - Fine-grained control over the query process
1916
+ *
1917
+ * For most use cases, prefer the higher-level `client.chat` API instead.
1918
+ */
1919
+ declare class SyftAIResource {
1920
+ /**
1921
+ * Build headers for SyftAI-Space request.
1922
+ */
1923
+ private buildHeaders;
1924
+ /**
1925
+ * Query a data source endpoint directly.
1926
+ *
1927
+ * @param options - Query options
1928
+ * @returns Array of Document objects
1929
+ * @throws {RetrievalError} If the query fails
1930
+ */
1931
+ queryDataSource(options: QueryDataSourceOptions): Promise<Document[]>;
1932
+ /**
1933
+ * Query a model endpoint directly.
1934
+ *
1935
+ * @param options - Query options
1936
+ * @returns Generated response text
1937
+ * @throws {GenerationError} If generation fails
1938
+ */
1939
+ queryModel(options: QueryModelOptions): Promise<string>;
1940
+ /**
1941
+ * Stream a model response directly.
1942
+ *
1943
+ * @param options - Query options
1944
+ * @yields Response text chunks as they arrive
1945
+ * @throws {GenerationError} If generation fails
1946
+ */
1947
+ queryModelStream(options: QueryModelOptions): AsyncGenerator<string, void, unknown>;
1948
+ }
1949
+
1950
+ /**
1951
+ * Configuration options for SyftHubClient.
1952
+ */
1953
+ interface SyftHubClientOptions {
1954
+ /**
1955
+ * Base URL for the SyftHub API.
1956
+ * Falls back to SYFTHUB_URL environment variable.
1957
+ * @example 'https://hub.syft.com'
1958
+ */
1959
+ baseUrl?: string;
1960
+ /**
1961
+ * Request timeout in milliseconds.
1962
+ * @default 30000
1963
+ */
1964
+ timeout?: number;
1965
+ /**
1966
+ * Base URL for the aggregator service (optional).
1967
+ * Falls back to SYFTHUB_AGGREGATOR_URL environment variable.
1968
+ * Defaults to {baseUrl}/aggregator/api/v1
1969
+ */
1970
+ aggregatorUrl?: string;
1971
+ /**
1972
+ * Base URL for the accounting service (optional).
1973
+ * Falls back to SYFTHUB_ACCOUNTING_URL environment variable.
1974
+ */
1975
+ accountingUrl?: string;
1976
+ /**
1977
+ * Email for accounting service authentication (optional).
1978
+ * Falls back to SYFTHUB_ACCOUNTING_EMAIL environment variable.
1979
+ */
1980
+ accountingEmail?: string;
1981
+ /**
1982
+ * Password for accounting service authentication (optional).
1983
+ * Falls back to SYFTHUB_ACCOUNTING_PASSWORD environment variable.
1984
+ */
1985
+ accountingPassword?: string;
1986
+ }
1987
+ /**
1988
+ * SyftHub SDK client for interacting with the SyftHub API.
1989
+ *
1990
+ * @example
1991
+ * // Basic usage
1992
+ * import { SyftHubClient } from '@syfthub/sdk';
1993
+ *
1994
+ * const client = new SyftHubClient({ baseUrl: 'https://hub.syft.com' });
1995
+ *
1996
+ * // Or use environment variable
1997
+ * // Set SYFTHUB_URL=https://hub.syft.com
1998
+ * const client = new SyftHubClient();
1999
+ *
2000
+ * @example
2001
+ * // Authentication
2002
+ * const user = await client.auth.login('alice', 'password123');
2003
+ * console.log(`Logged in as ${user.username}`);
2004
+ *
2005
+ * // Get current user
2006
+ * const me = await client.auth.me();
2007
+ *
2008
+ * @example
2009
+ * // Browse endpoints
2010
+ * for await (const endpoint of client.hub.browse()) {
2011
+ * console.log(endpoint.name);
2012
+ * }
2013
+ *
2014
+ * @example
2015
+ * // Manage your endpoints
2016
+ * const endpoint = await client.myEndpoints.create({
2017
+ * name: 'My Model',
2018
+ * type: 'model',
2019
+ * visibility: 'public',
2020
+ * });
2021
+ *
2022
+ * @example
2023
+ * // Token persistence
2024
+ * const tokens = client.getTokens();
2025
+ * // Save tokens to storage...
2026
+ *
2027
+ * // Later, restore tokens
2028
+ * client.setTokens(savedTokens);
2029
+ */
2030
+ declare class SyftHubClient {
2031
+ private readonly http;
2032
+ private readonly options;
2033
+ private readonly aggregatorUrl;
2034
+ private _auth?;
2035
+ private _users?;
2036
+ private _myEndpoints?;
2037
+ private _hub?;
2038
+ private _accounting?;
2039
+ private _chat?;
2040
+ private _syftai?;
2041
+ /**
2042
+ * Create a new SyftHub client.
2043
+ *
2044
+ * @param options - Configuration options
2045
+ * @throws {SyftHubError} If baseUrl is not provided and SYFTHUB_URL is not set (in non-browser environments)
2046
+ */
2047
+ constructor(options?: SyftHubClientOptions);
2048
+ /**
2049
+ * Authentication resource for login, register, and session management.
2050
+ *
2051
+ * @example
2052
+ * const user = await client.auth.login('alice', 'password');
2053
+ * await client.auth.logout();
2054
+ */
2055
+ get auth(): AuthResource;
2056
+ /**
2057
+ * Users resource for profile management.
2058
+ *
2059
+ * @example
2060
+ * const user = await client.users.update({ fullName: 'Alice Smith' });
2061
+ * const available = await client.users.checkUsername('newname');
2062
+ */
2063
+ get users(): UsersResource;
2064
+ /**
2065
+ * My Endpoints resource for managing your own endpoints.
2066
+ *
2067
+ * @example
2068
+ * const endpoints = await client.myEndpoints.list().all();
2069
+ * const endpoint = await client.myEndpoints.create({ name: 'My API', type: 'model' });
2070
+ */
2071
+ get myEndpoints(): MyEndpointsResource;
2072
+ /**
2073
+ * Hub resource for browsing public endpoints.
2074
+ *
2075
+ * @example
2076
+ * for await (const endpoint of client.hub.browse()) {
2077
+ * console.log(endpoint.name);
2078
+ * }
2079
+ */
2080
+ get hub(): HubResource;
2081
+ /**
2082
+ * Accounting resource for billing and transactions.
2083
+ *
2084
+ * The accounting service is external and uses separate credentials
2085
+ * (email/password Basic auth) from SyftHub's JWT authentication.
2086
+ *
2087
+ * Credentials can be provided via:
2088
+ * - Constructor options: accountingUrl, accountingEmail, accountingPassword
2089
+ * - Environment variables: SYFTHUB_ACCOUNTING_URL, SYFTHUB_ACCOUNTING_EMAIL, SYFTHUB_ACCOUNTING_PASSWORD
2090
+ *
2091
+ * @throws {SyftHubError} If accounting credentials are not configured
2092
+ *
2093
+ * @example
2094
+ * const user = await client.accounting.getUser();
2095
+ * console.log(`Balance: ${user.balance}`);
2096
+ *
2097
+ * // Create a transaction
2098
+ * const tx = await client.accounting.createTransaction({
2099
+ * recipientEmail: 'bob@example.com',
2100
+ * amount: 10.0
2101
+ * });
2102
+ */
2103
+ get accounting(): AccountingResource;
2104
+ /**
2105
+ * Chat resource for RAG-augmented conversations via the Aggregator.
2106
+ *
2107
+ * This resource provides high-level chat functionality that integrates
2108
+ * with the SyftHub Aggregator service for RAG workflows.
2109
+ *
2110
+ * @example
2111
+ * // Simple chat completion
2112
+ * const response = await client.chat.complete({
2113
+ * prompt: 'What is machine learning?',
2114
+ * model: 'alice/gpt-model',
2115
+ * dataSources: ['bob/ml-docs'],
2116
+ * });
2117
+ * console.log(response.response);
2118
+ *
2119
+ * // Streaming chat
2120
+ * for await (const event of client.chat.stream(options)) {
2121
+ * if (event.type === 'token') {
2122
+ * process.stdout.write(event.content);
2123
+ * }
2124
+ * }
2125
+ *
2126
+ * // Get available endpoints
2127
+ * const models = await client.chat.getAvailableModels();
2128
+ * const sources = await client.chat.getAvailableDataSources();
2129
+ */
2130
+ get chat(): ChatResource;
2131
+ /**
2132
+ * SyftAI-Space resource for direct endpoint queries (low-level API).
2133
+ *
2134
+ * This resource provides direct access to SyftAI-Space endpoints without
2135
+ * going through the aggregator. Use this when you need custom RAG pipelines
2136
+ * or fine-grained control over queries.
2137
+ *
2138
+ * For most use cases, prefer the higher-level `client.chat` API instead.
2139
+ *
2140
+ * @example
2141
+ * // Query a data source directly
2142
+ * const docs = await client.syftai.queryDataSource({
2143
+ * endpoint: { url: 'http://syftai:8080', slug: 'docs' },
2144
+ * query: 'What is Python?',
2145
+ * userEmail: 'alice@example.com',
2146
+ * });
2147
+ *
2148
+ * // Query a model directly
2149
+ * const response = await client.syftai.queryModel({
2150
+ * endpoint: { url: 'http://syftai:8080', slug: 'gpt-model' },
2151
+ * messages: [{ role: 'user', content: 'Hello!' }],
2152
+ * userEmail: 'alice@example.com',
2153
+ * });
2154
+ */
2155
+ get syftai(): SyftAIResource;
2156
+ /**
2157
+ * Get current authentication tokens.
2158
+ *
2159
+ * Use this to persist tokens for later sessions.
2160
+ *
2161
+ * @returns Current tokens or null if not authenticated
2162
+ *
2163
+ * @example
2164
+ * const tokens = client.getTokens();
2165
+ * if (tokens) {
2166
+ * localStorage.setItem('tokens', JSON.stringify(tokens));
2167
+ * }
2168
+ */
2169
+ getTokens(): AuthTokens | null;
2170
+ /**
2171
+ * Set authentication tokens.
2172
+ *
2173
+ * Use this to restore a session from previously saved tokens.
2174
+ *
2175
+ * @param tokens - Tokens to set
2176
+ *
2177
+ * @example
2178
+ * const saved = JSON.parse(localStorage.getItem('tokens'));
2179
+ * if (saved) {
2180
+ * client.setTokens(saved);
2181
+ * }
2182
+ */
2183
+ setTokens(tokens: AuthTokens): void;
2184
+ /**
2185
+ * Check if the client is currently authenticated.
2186
+ *
2187
+ * @returns True if tokens are present
2188
+ */
2189
+ get isAuthenticated(): boolean;
2190
+ /**
2191
+ * Check if accounting service is configured.
2192
+ *
2193
+ * Use this to check if accounting credentials are available before
2194
+ * accessing the `accounting` property, which will throw if not configured.
2195
+ *
2196
+ * @returns True if accounting url, email, and password are all configured
2197
+ *
2198
+ * @example
2199
+ * if (client.isAccountingConfigured) {
2200
+ * const user = await client.accounting.getUser();
2201
+ * }
2202
+ */
2203
+ get isAccountingConfigured(): boolean;
2204
+ /**
2205
+ * Close the client and clean up resources.
2206
+ *
2207
+ * Currently a no-op, but may be used in future for connection pooling.
2208
+ */
2209
+ close(): void;
2210
+ }
2211
+
2212
+ export { APIError, AccountingAccountExistsError, type AccountingCredentials, AccountingResource, type AccountingResourceOptions, AccountingServiceUnavailableError, type AccountingUser, AggregatorError, type AuthTokens, AuthenticationError, AuthorizationError, type BrowseOptions, type ChatMetadata, type ChatOptions, ChatResource, type ChatResponse, type ChatStreamEvent, ConfigurationError, type Connection, type CreateDelegatedTransactionInput, type CreateTransactionInput, CreatorType, type Document, type DoneEvent, type Endpoint, type EndpointCreateInput, type EndpointPublic, type EndpointRef, EndpointResolutionError, EndpointType, type EndpointUpdateInput, type ErrorEvent, GenerationError, type GenerationStartEvent, InvalidAccountingPasswordError, type ListEndpointsOptions, type Message, NetworkError, NotFoundError, OrganizationRole, type PageFetcher, PageIterator, type PasswordChangeInput, type Policy, type QueryDataSourceOptions, type QueryModelOptions, type RetrievalCompleteEvent, RetrievalError, type RetrievalStartEvent, type SourceCompleteEvent, type SourceInfo, type SourceStatus, SyftAIResource, SyftHubClient, type SyftHubClientOptions, SyftHubError, type TokenEvent, type Transaction, type TransactionResponse, TransactionStatus, type TransactionTokenResponse, type TransactionsOptions, type TrendingOptions, type UpdatePasswordInput, type User, UserAlreadyExistsError, type UserRegisterInput, UserRole, type UserUpdateInput, ValidationError, Visibility, createAccountingResource, getEndpointOwnerType, getEndpointPublicPath, isTransactionCancelled, isTransactionCompleted, isTransactionPending, parseTransaction };