@syfthub/sdk 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -21,8 +21,8 @@ interface AuthTokens {
21
21
  * Internal HTTP client for making API requests.
22
22
  *
23
23
  * Handles:
24
- * - Bearer token authentication
25
- * - Automatic token refresh on 401 responses
24
+ * - Bearer token authentication (JWT or API token)
25
+ * - Automatic token refresh on 401 responses (JWT only)
26
26
  * - JSON serialization/deserialization
27
27
  * - snake_case <-> camelCase conversion
28
28
  * - Error handling and exception mapping
@@ -32,6 +32,7 @@ declare class HTTPClient {
32
32
  private readonly timeout;
33
33
  private accessToken;
34
34
  private refreshToken;
35
+ private apiToken;
35
36
  private isRefreshing;
36
37
  private refreshPromise;
37
38
  /**
@@ -42,21 +43,38 @@ declare class HTTPClient {
42
43
  */
43
44
  constructor(baseUrl: string, timeout?: number);
44
45
  /**
45
- * Set authentication tokens.
46
+ * Set JWT authentication tokens.
47
+ * Clears any API token if set.
46
48
  */
47
49
  setTokens(access: string, refresh: string): void;
48
50
  /**
49
- * Get current authentication tokens.
51
+ * Set API token for authentication.
52
+ * Clears any JWT tokens if set.
53
+ *
54
+ * @param token - The API token (starts with "syft_")
55
+ */
56
+ setApiToken(token: string): void;
57
+ /**
58
+ * Get current JWT authentication tokens.
59
+ * Returns null if using API token authentication.
50
60
  */
51
61
  getTokens(): AuthTokens | null;
52
62
  /**
53
- * Clear authentication tokens.
63
+ * Check if using API token authentication.
64
+ */
65
+ isUsingApiToken(): boolean;
66
+ /**
67
+ * Clear all authentication (JWT and API tokens).
54
68
  */
55
69
  clearTokens(): void;
56
70
  /**
57
- * Check if the client has valid tokens.
71
+ * Check if the client has valid authentication (JWT or API token).
58
72
  */
59
73
  hasTokens(): boolean;
74
+ /**
75
+ * Get the current bearer token (API token or JWT access token).
76
+ */
77
+ private getBearerToken;
60
78
  /**
61
79
  * Make a GET request.
62
80
  */
@@ -108,6 +126,184 @@ declare class HTTPClient {
108
126
  private attemptTokenRefresh;
109
127
  }
110
128
 
129
+ /**
130
+ * API Token models for managing personal access tokens.
131
+ */
132
+ /**
133
+ * Permission scopes for API tokens.
134
+ */
135
+ type APITokenScope = 'read' | 'write' | 'full';
136
+ /**
137
+ * API token representation (without the actual token value).
138
+ */
139
+ interface APIToken {
140
+ /** Unique token identifier */
141
+ id: number;
142
+ /** User-friendly label for the token */
143
+ name: string;
144
+ /** First characters of the token for identification (e.g., 'syft_pat_aB3d') */
145
+ tokenPrefix: string;
146
+ /** Permission scopes */
147
+ scopes: readonly APITokenScope[];
148
+ /** Expiration timestamp, null if never expires */
149
+ expiresAt: Date | null;
150
+ /** Last time the token was used for authentication */
151
+ lastUsedAt: Date | null;
152
+ /** IP address from the last authentication */
153
+ lastUsedIp: string | null;
154
+ /** Whether the token is active (not revoked) */
155
+ isActive: boolean;
156
+ /** When the token was created */
157
+ createdAt: Date;
158
+ /** When the token was last updated */
159
+ updatedAt: Date | null;
160
+ }
161
+ /**
162
+ * Response when creating a new API token.
163
+ * IMPORTANT: The token is only shown ONCE in this response!
164
+ */
165
+ interface APITokenCreateResponse extends APIToken {
166
+ /** The full API token. SAVE THIS NOW - it will not be shown again! */
167
+ token: string;
168
+ }
169
+ /**
170
+ * Input for creating a new API token.
171
+ */
172
+ interface CreateAPITokenInput {
173
+ /** User-friendly label for the token (e.g., 'CI/CD Pipeline') */
174
+ name: string;
175
+ /** Permission scopes. Defaults to ['full'] if not specified. */
176
+ scopes?: APITokenScope[];
177
+ /** Optional expiration timestamp. Null means never expires. */
178
+ expiresAt?: Date | null;
179
+ }
180
+ /**
181
+ * Input for updating an API token.
182
+ */
183
+ interface UpdateAPITokenInput {
184
+ /** New name for the token */
185
+ name: string;
186
+ }
187
+ /**
188
+ * Response for listing API tokens.
189
+ */
190
+ interface APITokenListResponse {
191
+ /** List of API tokens */
192
+ tokens: APIToken[];
193
+ /** Total number of tokens */
194
+ total: number;
195
+ }
196
+
197
+ /**
198
+ * Resource for managing API tokens.
199
+ */
200
+
201
+ /**
202
+ * Resource for managing API tokens.
203
+ *
204
+ * API tokens provide an alternative to username/password authentication.
205
+ * They are ideal for CI/CD pipelines, scripts, and programmatic access.
206
+ *
207
+ * @example
208
+ * // Create a new token
209
+ * const result = await client.apiTokens.create({
210
+ * name: 'CI/CD Pipeline',
211
+ * scopes: ['write'],
212
+ * });
213
+ * console.log('Save this token:', result.token);
214
+ *
215
+ * // List all tokens
216
+ * const { tokens } = await client.apiTokens.list();
217
+ *
218
+ * // Revoke a token
219
+ * await client.apiTokens.revoke(tokenId);
220
+ */
221
+ declare class APITokensResource {
222
+ private readonly http;
223
+ constructor(http: HTTPClient);
224
+ /**
225
+ * Create a new API token.
226
+ *
227
+ * IMPORTANT: The returned token is only shown ONCE!
228
+ * Make sure to save it immediately - it cannot be retrieved later.
229
+ *
230
+ * @param input - Token creation options
231
+ * @returns The created token with the full token value
232
+ *
233
+ * @example
234
+ * const result = await client.apiTokens.create({
235
+ * name: 'CI/CD Pipeline',
236
+ * scopes: ['write'],
237
+ * expiresAt: new Date('2025-12-31'),
238
+ * });
239
+ *
240
+ * // SAVE THIS TOKEN - it will not be shown again!
241
+ * console.log(result.token);
242
+ */
243
+ create(input: CreateAPITokenInput): Promise<APITokenCreateResponse>;
244
+ /**
245
+ * List all API tokens for the current user.
246
+ *
247
+ * By default, only active tokens are returned.
248
+ * Note: The full token value is never returned - only the prefix.
249
+ *
250
+ * @param options - List options
251
+ * @returns List of tokens and total count
252
+ *
253
+ * @example
254
+ * // List active tokens
255
+ * const { tokens, total } = await client.apiTokens.list();
256
+ *
257
+ * // Include revoked tokens
258
+ * const all = await client.apiTokens.list({ includeInactive: true });
259
+ */
260
+ list(options?: {
261
+ includeInactive?: boolean;
262
+ skip?: number;
263
+ limit?: number;
264
+ }): Promise<APITokenListResponse>;
265
+ /**
266
+ * Get a single API token by ID.
267
+ *
268
+ * Note: The full token value is never returned - only the prefix.
269
+ *
270
+ * @param tokenId - The token ID
271
+ * @returns The token details
272
+ *
273
+ * @example
274
+ * const token = await client.apiTokens.get(123);
275
+ * console.log(token.name, token.lastUsedAt);
276
+ */
277
+ get(tokenId: number): Promise<APIToken>;
278
+ /**
279
+ * Update an API token's name.
280
+ *
281
+ * Only the name can be updated. Scopes and expiration cannot be
282
+ * changed after creation.
283
+ *
284
+ * @param tokenId - The token ID
285
+ * @param input - Update options
286
+ * @returns The updated token
287
+ *
288
+ * @example
289
+ * const updated = await client.apiTokens.update(123, {
290
+ * name: 'New Name',
291
+ * });
292
+ */
293
+ update(tokenId: number, input: UpdateAPITokenInput): Promise<APIToken>;
294
+ /**
295
+ * Revoke an API token.
296
+ *
297
+ * The token becomes immediately unusable. This action cannot be undone.
298
+ *
299
+ * @param tokenId - The token ID to revoke
300
+ *
301
+ * @example
302
+ * await client.apiTokens.revoke(123);
303
+ */
304
+ revoke(tokenId: number): Promise<void>;
305
+ }
306
+
111
307
  /**
112
308
  * Visibility levels for endpoints.
113
309
  */
@@ -116,7 +312,7 @@ declare const Visibility: {
116
312
  readonly PUBLIC: "public";
117
313
  /** Only visible to the owner and collaborators */
118
314
  readonly PRIVATE: "private";
119
- /** Visible to authenticated users within the organization */
315
+ /** Behaves like private only visible to the owner */
120
316
  readonly INTERNAL: "internal";
121
317
  };
122
318
  type Visibility = (typeof Visibility)[keyof typeof Visibility];
@@ -128,6 +324,10 @@ declare const EndpointType: {
128
324
  readonly MODEL: "model";
129
325
  /** Data source endpoint */
130
326
  readonly DATA_SOURCE: "data_source";
327
+ /** Both model and data source endpoint */
328
+ readonly MODEL_DATA_SOURCE: "model_data_source";
329
+ /** Agent endpoint with session-based interaction */
330
+ readonly AGENT: "agent";
131
331
  };
132
332
  type EndpointType = (typeof EndpointType)[keyof typeof EndpointType];
133
333
  /**
@@ -142,18 +342,6 @@ declare const UserRole: {
142
342
  readonly GUEST: "guest";
143
343
  };
144
344
  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
345
 
158
346
  /**
159
347
  * User account information.
@@ -172,6 +360,10 @@ interface User {
172
360
  readonly domain: string | null;
173
361
  /** Custom aggregator URL for RAG/chat workflows */
174
362
  readonly aggregatorUrl: string | null;
363
+ /** Markdown bio shown on the user's public profile */
364
+ readonly bio?: string | null;
365
+ /** Whether the user's email is shown on their public profile */
366
+ readonly isEmailPublic?: boolean;
175
367
  }
176
368
  /**
177
369
  * Input for user registration.
@@ -208,6 +400,52 @@ interface UserUpdateInput {
208
400
  domain?: string;
209
401
  /** Custom aggregator URL for RAG/chat workflows */
210
402
  aggregatorUrl?: string;
403
+ /** Markdown bio shown on the user's public profile */
404
+ bio?: string;
405
+ /** Whether the user's email is shown on their public profile */
406
+ isEmailPublic?: boolean;
407
+ }
408
+ /**
409
+ * Result of user registration.
410
+ *
411
+ * When `requiresEmailVerification` is true, tokens are null and the client
412
+ * must call `auth.verifyOtp()` before the user can log in.
413
+ */
414
+ interface RegisterResult {
415
+ readonly user: User;
416
+ /** Whether the user must verify their email via OTP before receiving tokens. */
417
+ readonly requiresEmailVerification: boolean;
418
+ }
419
+ /**
420
+ * Input for verifying a registration OTP.
421
+ */
422
+ interface VerifyOTPInput {
423
+ email: string;
424
+ /** 6-digit numeric code sent to the user's email */
425
+ code: string;
426
+ }
427
+ /**
428
+ * Input for requesting a password reset.
429
+ */
430
+ interface PasswordResetRequestInput {
431
+ email: string;
432
+ }
433
+ /**
434
+ * Input for confirming a password reset with OTP.
435
+ */
436
+ interface PasswordResetConfirmInput {
437
+ email: string;
438
+ /** 6-digit numeric OTP code */
439
+ code: string;
440
+ newPassword: string;
441
+ }
442
+ /**
443
+ * Platform authentication configuration (from GET /auth/config).
444
+ */
445
+ interface AuthConfig {
446
+ readonly requireEmailVerification: boolean;
447
+ readonly smtpConfigured: boolean;
448
+ readonly passwordResetEnabled: boolean;
211
449
  }
212
450
  /**
213
451
  * Input for changing password.
@@ -228,6 +466,75 @@ interface AccountingCredentials {
228
466
  /** Password for authenticating with the accounting service (null if not configured) */
229
467
  readonly password: string | null;
230
468
  }
469
+ /**
470
+ * Input for sending a heartbeat.
471
+ */
472
+ interface HeartbeatInput {
473
+ /** Full URL of this space (e.g., "https://myspace.example.com") */
474
+ url: string;
475
+ /** Time-to-live in seconds (1-3600, server caps at 600). Default is 300. */
476
+ ttlSeconds?: number;
477
+ }
478
+ /**
479
+ * Response from the heartbeat endpoint.
480
+ *
481
+ * The heartbeat mechanism allows SyftAI Spaces to signal their availability
482
+ * to SyftHub. The server returns the effective TTL (which may be capped)
483
+ * and the expiration time.
484
+ */
485
+ interface HeartbeatResponse {
486
+ /** Status of the heartbeat (typically 'ok') */
487
+ readonly status: string;
488
+ /** When the heartbeat was received (ISO 8601 string) */
489
+ readonly receivedAt: Date;
490
+ /** When the heartbeat will expire (ISO 8601 string) */
491
+ readonly expiresAt: Date;
492
+ /** Extracted domain from the URL */
493
+ readonly domain: string;
494
+ /** Effective TTL applied (may be capped by server) */
495
+ readonly ttlSeconds: number;
496
+ }
497
+ /**
498
+ * A user's aggregator configuration.
499
+ *
500
+ * Aggregators are custom RAG orchestration service endpoints that users can
501
+ * configure to use for chat operations. Each user can have multiple aggregator
502
+ * configurations, with one set as the default.
503
+ */
504
+ interface UserAggregator {
505
+ /** Unique aggregator configuration ID */
506
+ readonly id: number;
507
+ /** Owner user ID */
508
+ readonly userId: number;
509
+ /** Display name for the aggregator */
510
+ readonly name: string;
511
+ /** Aggregator service URL */
512
+ readonly url: string;
513
+ /** Whether this is the user's default aggregator */
514
+ readonly isDefault: boolean;
515
+ /** When the aggregator was created */
516
+ readonly createdAt: Date;
517
+ /** When the aggregator was last updated */
518
+ readonly updatedAt: Date;
519
+ }
520
+ /**
521
+ * Input for creating an aggregator configuration.
522
+ */
523
+ interface UserAggregatorCreateInput {
524
+ /** Display name for the aggregator */
525
+ name: string;
526
+ /** Aggregator service URL */
527
+ url: string;
528
+ }
529
+ /**
530
+ * Input for updating an aggregator configuration.
531
+ */
532
+ interface UserAggregatorUpdateInput {
533
+ /** New display name (optional) */
534
+ name?: string;
535
+ /** New aggregator URL (optional) */
536
+ url?: string;
537
+ }
231
538
 
232
539
  /**
233
540
  * Policy configuration for an endpoint.
@@ -253,8 +560,7 @@ interface Connection {
253
560
  */
254
561
  interface Endpoint {
255
562
  readonly id: number;
256
- readonly userId: number | null;
257
- readonly organizationId: number | null;
563
+ readonly userId: number;
258
564
  readonly name: string;
259
565
  readonly slug: string;
260
566
  readonly description: string;
@@ -357,13 +663,6 @@ interface EndpointUpdateInput {
357
663
  connect?: Connection[];
358
664
  contributors?: number[];
359
665
  }
360
- /**
361
- * Get the owner type for an endpoint.
362
- *
363
- * @param endpoint - The endpoint to check
364
- * @returns 'user' if user-owned, 'organization' if org-owned
365
- */
366
- declare function getEndpointOwnerType(endpoint: Endpoint): 'user' | 'organization';
367
666
  /**
368
667
  * Get the full path for a public endpoint (owner/slug format).
369
668
  *
@@ -387,146 +686,66 @@ interface SyncEndpointsResponse {
387
686
  }
388
687
 
389
688
  /**
390
- * Accounting Models
391
- *
392
- * Models for the external accounting service. The accounting service manages
393
- * user balances and transactions, and uses its own authentication separate
394
- * from SyftHub.
395
- */
396
- /**
397
- * Transaction status in the accounting service.
398
- */
399
- declare const TransactionStatus: {
400
- /** Transaction created, awaiting confirmation */
401
- readonly PENDING: "pending";
402
- /** Transaction confirmed, funds transferred */
403
- readonly COMPLETED: "completed";
404
- /** Transaction cancelled, no funds transferred */
405
- readonly CANCELLED: "cancelled";
406
- };
407
- type TransactionStatus = (typeof TransactionStatus)[keyof typeof TransactionStatus];
408
- /**
409
- * Who created or resolved a transaction.
410
- */
411
- declare const CreatorType: {
412
- /** System-initiated transaction */
413
- readonly SYSTEM: "system";
414
- /** Sender-initiated transaction */
415
- readonly SENDER: "sender";
416
- /** Recipient-initiated transaction (delegated) */
417
- readonly RECIPIENT: "recipient";
418
- };
419
- type CreatorType = (typeof CreatorType)[keyof typeof CreatorType];
420
- /**
421
- * User from accounting service with balance.
422
- *
423
- * This represents the user's account in the external accounting service,
424
- * which is separate from the SyftHub user account.
425
- */
426
- interface AccountingUser {
427
- readonly id: string;
428
- readonly email: string;
429
- readonly balance: number;
430
- readonly organization: string | null;
431
- }
432
- /**
433
- * Transaction record from accounting service.
434
- *
435
- * Transactions go through a lifecycle:
436
- * 1. Created (status=PENDING)
437
- * 2. Confirmed or Cancelled (status=COMPLETED or CANCELLED)
689
+ * Accounting Models (MPP Wallet)
438
690
  *
439
- * The createdBy field indicates who initiated the transaction:
440
- * - SENDER: Direct transaction by the payer
441
- * - RECIPIENT: Delegated transaction using a token
442
- * - SYSTEM: System-initiated transaction
443
- *
444
- * The resolvedBy field indicates who confirmed/cancelled.
445
- */
446
- interface Transaction {
447
- readonly id: string;
448
- readonly senderEmail: string;
449
- readonly recipientEmail: string;
450
- readonly amount: number;
451
- readonly status: TransactionStatus;
452
- readonly createdBy: CreatorType;
453
- readonly resolvedBy: CreatorType | null;
454
- readonly createdAt: Date;
455
- readonly resolvedAt: Date | null;
456
- readonly appName: string | null;
457
- readonly appEpPath: string | null;
458
- }
459
- /**
460
- * Input for creating a direct transaction.
691
+ * Models for the MPP wallet system. Replaces the previous external accounting
692
+ * service models with wallet-based types for the Micropayment Protocol.
461
693
  */
462
- interface CreateTransactionInput {
463
- /** Email of the recipient */
464
- recipientEmail: string;
465
- /** Amount to transfer (must be > 0) */
466
- amount: number;
467
- /** Optional app name for context (e.g., "syftai-space") */
468
- appName?: string;
469
- /** Optional endpoint path for context (e.g., "alice/model") */
470
- appEpPath?: string;
471
- }
472
694
  /**
473
- * Input for creating a delegated transaction.
695
+ * Wallet information for the current user.
474
696
  */
475
- interface CreateDelegatedTransactionInput {
476
- /** Email of the sender who created the token */
477
- senderEmail: string;
478
- /** Amount to transfer (must be > 0) */
479
- amount: number;
480
- /** JWT token from sender's createTransactionToken() */
481
- token: string;
697
+ interface WalletInfo {
698
+ /** Wallet address (null if no wallet configured) */
699
+ address: string | null;
700
+ /** Whether a wallet exists for this user */
701
+ exists: boolean;
482
702
  }
483
703
  /**
484
- * Input for updating password.
704
+ * Wallet balance and recent activity.
485
705
  */
486
- interface UpdatePasswordInput {
487
- /** Current password for verification */
488
- currentPassword: string;
489
- /** New password to set */
490
- newPassword: string;
706
+ interface WalletBalance {
707
+ /** Current balance amount */
708
+ balance: number;
709
+ /** Currency identifier */
710
+ currency: string;
711
+ /** Recent transactions for this wallet */
712
+ recent_transactions: WalletTransaction[];
713
+ /** Whether a wallet is configured */
714
+ wallet_configured: boolean;
491
715
  }
492
716
  /**
493
- * Raw transaction response from API (before date parsing).
717
+ * A wallet transaction record.
494
718
  */
495
- interface TransactionResponse {
719
+ interface WalletTransaction {
720
+ /** Unique transaction identifier */
496
721
  id: string;
497
- senderEmail: string;
498
- recipientEmail: string;
722
+ /** Email of the sender */
723
+ sender_email: string;
724
+ /** Email of the recipient */
725
+ recipient_email: string;
726
+ /** Transaction amount */
499
727
  amount: number;
500
- status: TransactionStatus;
501
- createdBy: CreatorType;
502
- resolvedBy: CreatorType | null;
503
- createdAt: string;
504
- resolvedAt: string | null;
505
- appName: string | null;
506
- appEpPath: string | null;
728
+ /** Transaction status (e.g., "completed", "pending") */
729
+ status: string;
730
+ /** When the transaction was created (ISO 8601) */
731
+ created_at: string;
732
+ /** App name associated with the transaction */
733
+ app_name?: string;
734
+ /** Endpoint path associated with the transaction */
735
+ app_ep_path?: string;
507
736
  }
508
737
  /**
509
- * Token response from createTransactionToken.
738
+ * Response from transaction tokens endpoint.
739
+ *
740
+ * @deprecated Transaction tokens are no longer used. Payments are handled
741
+ * via the MPP 402 flow. Kept for backward compatibility with getTransactionTokens().
510
742
  */
511
- interface TransactionTokenResponse {
512
- token: string;
743
+ interface TransactionTokensResponse {
744
+ /** Mapping of owner_username to transaction token */
745
+ tokens: Record<string, string>;
746
+ /** Mapping of owner_username to error message (for failed tokens) */
747
+ errors: Record<string, string>;
513
748
  }
514
- /**
515
- * Parse a transaction response into a Transaction object.
516
- */
517
- declare function parseTransaction(response: TransactionResponse): Transaction;
518
- /**
519
- * Check if a transaction is pending.
520
- */
521
- declare function isTransactionPending(tx: Transaction): boolean;
522
- /**
523
- * Check if a transaction is completed.
524
- */
525
- declare function isTransactionCompleted(tx: Transaction): boolean;
526
- /**
527
- * Check if a transaction is cancelled.
528
- */
529
- declare function isTransactionCancelled(tx: Transaction): boolean;
530
749
 
531
750
  /**
532
751
  * Chat-related types for the SyftHub SDK.
@@ -633,6 +852,8 @@ interface ChatResponse {
633
852
  metadata: ChatMetadata;
634
853
  /** Token usage if available */
635
854
  usage?: TokenUsage;
855
+ /** Normalized contribution scores per source (owner/slug to fraction 0-1) */
856
+ profitShare?: Record<string, number>;
636
857
  }
637
858
  /**
638
859
  * A chat message for model queries.
@@ -665,6 +886,14 @@ interface ChatOptions {
665
886
  signal?: AbortSignal;
666
887
  /** Custom aggregator URL to use instead of the default */
667
888
  aggregatorUrl?: string;
889
+ /** Peer token for NATS tunneling (auto-fetched if tunneling endpoints detected) */
890
+ peerToken?: string;
891
+ /** Peer channel for NATS replies (auto-fetched if tunneling endpoints detected) */
892
+ peerChannel?: string;
893
+ /** Use guest mode for unauthenticated access to policy-free endpoints */
894
+ guestMode?: boolean;
895
+ /** Conversation history (prior turns) for multi-turn context */
896
+ messages?: Message[];
668
897
  }
669
898
  /**
670
899
  * Options for querying a data source directly.
@@ -680,6 +909,22 @@ interface QueryDataSourceOptions {
680
909
  topK?: number;
681
910
  /** Minimum similarity score (default: 0.5) */
682
911
  similarityThreshold?: number;
912
+ /**
913
+ * Pre-minted satellite token to send as `Authorization: Bearer`. If omitted,
914
+ * one is minted automatically when an owner is known (see `ownerUsername` /
915
+ * `endpoint.ownerUsername`).
916
+ */
917
+ authorizationToken?: string;
918
+ /**
919
+ * Endpoint owner username used as the satellite-token audience. Falls back to
920
+ * `endpoint.ownerUsername`.
921
+ */
922
+ ownerUsername?: string;
923
+ /**
924
+ * If true, settle an MPP `402 Payment Required` challenge via the Hub wallet
925
+ * and retry. If false (default), a `402` throws a `RetrievalError`.
926
+ */
927
+ pay?: boolean;
683
928
  }
684
929
  /**
685
930
  * Options for querying a model directly.
@@ -720,16 +965,43 @@ interface RetrievalCompleteEvent {
720
965
  totalDocuments: number;
721
966
  timeMs: number;
722
967
  }
968
+ /**
969
+ * Fired when document reranking begins (after all sources complete).
970
+ */
971
+ interface RerankingStartEvent {
972
+ type: 'reranking_start';
973
+ /** Number of documents being reranked */
974
+ documents: number;
975
+ }
976
+ /**
977
+ * Fired when document reranking completes.
978
+ */
979
+ interface RerankingCompleteEvent {
980
+ type: 'reranking_complete';
981
+ /** Number of documents after reranking */
982
+ documents: number;
983
+ /** Time taken for reranking in milliseconds */
984
+ timeMs: number;
985
+ }
723
986
  /**
724
987
  * Fired when model generation begins.
725
988
  */
726
989
  interface GenerationStartEvent {
727
990
  type: 'generation_start';
728
991
  }
992
+ /**
993
+ * Fired periodically during non-streaming model generation to indicate progress.
994
+ * Emitted every ~3 seconds while waiting for the model response.
995
+ */
996
+ interface GenerationHeartbeatEvent {
997
+ type: 'generation_heartbeat';
998
+ /** Milliseconds elapsed since generation_start */
999
+ elapsedMs: number;
1000
+ }
729
1001
  /**
730
1002
  * Fired for each token from the model.
731
1003
  */
732
- interface TokenEvent {
1004
+ interface TokenEvent$1 {
733
1005
  type: 'token';
734
1006
  content: string;
735
1007
  }
@@ -745,6 +1017,14 @@ interface DoneEvent {
745
1017
  metadata: ChatMetadata;
746
1018
  /** Token usage if available (only from non-streaming mode) */
747
1019
  usage?: TokenUsage;
1020
+ /** Normalized contribution scores per source (owner/slug to fraction 0-1) */
1021
+ profitShare?: Record<string, number>;
1022
+ /**
1023
+ * Clean response text with attribution markers stripped.
1024
+ * Present when attribution ran (data sources were used). Frontends should
1025
+ * replace the streamed content with this field to remove raw <cite:[N]> tags.
1026
+ */
1027
+ response?: string;
748
1028
  }
749
1029
  /**
750
1030
  * Fired on error.
@@ -773,7 +1053,7 @@ interface ErrorEvent {
773
1053
  * }
774
1054
  * }
775
1055
  */
776
- type ChatStreamEvent = RetrievalStartEvent | SourceCompleteEvent | RetrievalCompleteEvent | GenerationStartEvent | TokenEvent | DoneEvent | ErrorEvent;
1056
+ type ChatStreamEvent = RetrievalStartEvent | SourceCompleteEvent | RetrievalCompleteEvent | RerankingStartEvent | RerankingCompleteEvent | GenerationStartEvent | GenerationHeartbeatEvent | TokenEvent$1 | DoneEvent | ErrorEvent;
777
1057
 
778
1058
  /**
779
1059
  * Authentication resource for login, register, and session management.
@@ -859,7 +1139,7 @@ declare class AuthResource {
859
1139
  * }
860
1140
  * }
861
1141
  */
862
- register(input: UserRegisterInput): Promise<User>;
1142
+ register(input: UserRegisterInput): Promise<RegisterResult>;
863
1143
  /**
864
1144
  * Login with username/email and password.
865
1145
  *
@@ -901,6 +1181,81 @@ declare class AuthResource {
901
1181
  * @throws {ValidationError} If new password doesn't meet requirements
902
1182
  */
903
1183
  changePassword(currentPassword: string, newPassword: string): Promise<void>;
1184
+ /**
1185
+ * Get the platform's authentication configuration.
1186
+ *
1187
+ * No authentication required. Use this to determine whether email
1188
+ * verification or password reset is available.
1189
+ *
1190
+ * @returns AuthConfig with feature flags
1191
+ */
1192
+ getAuthConfig(): Promise<AuthConfig>;
1193
+ /**
1194
+ * Verify a registration OTP and receive auth tokens.
1195
+ *
1196
+ * After registering when email verification is required, call this with
1197
+ * the 6-digit code sent to the user's email.
1198
+ *
1199
+ * Idempotent: if the user is already verified, tokens are issued immediately.
1200
+ *
1201
+ * @param input - Email and 6-digit code
1202
+ * @returns The authenticated User
1203
+ * @throws {APIError} If the code is invalid or max attempts exceeded
1204
+ */
1205
+ verifyOtp(input: VerifyOTPInput): Promise<User>;
1206
+ /**
1207
+ * Resend the registration OTP code.
1208
+ *
1209
+ * Rate-limited. Always returns successfully to prevent email enumeration.
1210
+ *
1211
+ * @param email - Email address to resend the OTP to
1212
+ */
1213
+ resendOtp(email: string): Promise<void>;
1214
+ /**
1215
+ * Request a password reset OTP.
1216
+ *
1217
+ * Always returns successfully to prevent email enumeration.
1218
+ * If SMTP is not configured on the server, this is a no-op.
1219
+ *
1220
+ * @param input - Email address for password reset
1221
+ */
1222
+ requestPasswordReset(input: PasswordResetRequestInput): Promise<void>;
1223
+ /**
1224
+ * Confirm a password reset with OTP and set a new password.
1225
+ *
1226
+ * @param input - Email, 6-digit code, and new password
1227
+ * @throws {APIError} If the code is invalid or max attempts exceeded
1228
+ */
1229
+ confirmPasswordReset(input: PasswordResetConfirmInput): Promise<void>;
1230
+ /**
1231
+ * Get a peer token for NATS communication with tunneling spaces.
1232
+ *
1233
+ * Peer tokens are short-lived credentials that allow the aggregator to
1234
+ * communicate with tunneling SyftAI Spaces via NATS pub/sub.
1235
+ *
1236
+ * @param targetUsernames - Usernames of the tunneling spaces to communicate with
1237
+ * @returns PeerTokenResponse with token, channel, expiry, and NATS URL
1238
+ * @throws {AuthenticationError} If not authenticated
1239
+ *
1240
+ * @example
1241
+ * const peer = await client.auth.getPeerToken(['alice', 'bob']);
1242
+ * console.log(`Peer channel: ${peer.peerChannel}, expires in ${peer.expiresIn}s`);
1243
+ */
1244
+ getPeerToken(targetUsernames: string[]): Promise<PeerTokenResponse>;
1245
+ /**
1246
+ * Get a guest peer token for NATS communication without authentication.
1247
+ *
1248
+ * Guest peer tokens are rate-limited by IP address. They use the same
1249
+ * response format as authenticated peer tokens.
1250
+ *
1251
+ * @param targetUsernames - Usernames of the tunneling spaces to communicate with
1252
+ * @returns PeerTokenResponse with token, channel, expiry, and NATS URL
1253
+ *
1254
+ * @example
1255
+ * const peer = await client.auth.getGuestPeerToken(['alice']);
1256
+ * console.log(`Guest peer channel: ${peer.peerChannel}`);
1257
+ */
1258
+ getGuestPeerToken(targetUsernames: string[]): Promise<PeerTokenResponse>;
904
1259
  /**
905
1260
  * Get a satellite token for a specific audience (target service).
906
1261
  *
@@ -934,47 +1289,201 @@ declare class AuthResource {
934
1289
  * const tokens = await client.auth.getSatelliteTokens(['alice', 'bob']);
935
1290
  * console.log(`Got ${tokens.size} tokens`);
936
1291
  */
937
- getSatelliteTokens(audiences: string[]): Promise<Map<string, string>>;
1292
+ getSatelliteTokens(audiences: string[]): Promise<Map<string, string>>;
1293
+ /**
1294
+ * Get a guest satellite token for a specific audience (target service).
1295
+ *
1296
+ * Guest tokens allow unauthenticated users to access policy-free endpoints.
1297
+ * No authentication is required to call this method.
1298
+ *
1299
+ * @param audience - Target service identifier (username of the service owner)
1300
+ * @returns Satellite token response with token and expiry
1301
+ * @throws {ValidationError} If audience is invalid or inactive
1302
+ *
1303
+ * @example
1304
+ * // Get a guest token for querying alice's policy-free endpoints
1305
+ * const tokenResponse = await client.auth.getGuestSatelliteToken('alice');
1306
+ */
1307
+ getGuestSatelliteToken(audience: string): Promise<SatelliteTokenResponse>;
1308
+ /**
1309
+ * Get guest satellite tokens for multiple audiences in parallel.
1310
+ *
1311
+ * No authentication is required to call this method.
1312
+ *
1313
+ * @param audiences - Array of unique audience identifiers (usernames)
1314
+ * @returns Map of audience to satellite token
1315
+ *
1316
+ * @example
1317
+ * const tokens = await client.auth.getGuestSatelliteTokens(['alice', 'bob']);
1318
+ */
1319
+ getGuestSatelliteTokens(audiences: string[]): Promise<Map<string, string>>;
1320
+ /**
1321
+ * Get transaction tokens for multiple endpoint owners.
1322
+ *
1323
+ * @deprecated Transaction tokens are no longer needed. Payments are handled
1324
+ * via the MPP 402 flow. This method is kept for backward compatibility and
1325
+ * always returns empty tokens/errors.
1326
+ *
1327
+ * @param ownerUsernames - Array of endpoint owner usernames (ignored)
1328
+ * @returns TransactionTokensResponse with empty tokens and errors
1329
+ */
1330
+ getTransactionTokens(ownerUsernames: string[]): Promise<TransactionTokensResponse>;
1331
+ /**
1332
+ * Get the current access token (JWT or API token).
1333
+ *
1334
+ * This is used by the chat flow to pass the user's Hub token to the
1335
+ * aggregator for the MPP payment callback.
1336
+ *
1337
+ * @returns The current access token, or null if not authenticated
1338
+ */
1339
+ getAccessToken(): string | null;
1340
+ }
1341
+ /**
1342
+ * Response from peer token endpoint.
1343
+ */
1344
+ interface PeerTokenResponse {
1345
+ /** Short-lived token for NATS authentication */
1346
+ peerToken: string;
1347
+ /** Unique reply channel for receiving responses */
1348
+ peerChannel: string;
1349
+ /** Seconds until the token expires */
1350
+ expiresIn: number;
1351
+ /** NATS server URL for WebSocket connections */
1352
+ natsUrl: string;
1353
+ }
1354
+ /**
1355
+ * Response from satellite token endpoint.
1356
+ */
1357
+ interface SatelliteTokenResponse {
1358
+ /** RS256-signed JWT for the target service */
1359
+ targetToken: string;
1360
+ /** Seconds until the token expires */
1361
+ expiresIn: number;
1362
+ }
1363
+
1364
+ /**
1365
+ * Resource for managing user's aggregator configurations.
1366
+ *
1367
+ * Aggregators are custom RAG orchestration service endpoints that users can
1368
+ * configure to use for chat operations. Each user can have multiple aggregator
1369
+ * configurations, with one set as the default.
1370
+ *
1371
+ * The first aggregator created is automatically set as the default. Only one
1372
+ * aggregator can be the default at a time; setting a new default automatically
1373
+ * unsets the previous one.
1374
+ *
1375
+ * @example
1376
+ * // List all aggregators
1377
+ * const aggregators = await client.users.aggregators.list();
1378
+ * for (const agg of aggregators) {
1379
+ * console.log(`${agg.name}: ${agg.url}`);
1380
+ * }
1381
+ *
1382
+ * @example
1383
+ * // Create a new aggregator
1384
+ * const agg = await client.users.aggregators.create({
1385
+ * name: 'My Custom Aggregator',
1386
+ * url: 'https://my-aggregator.example.com'
1387
+ * });
1388
+ *
1389
+ * @example
1390
+ * // Set as default
1391
+ * const defaultAgg = await client.users.aggregators.setDefault(agg.id);
1392
+ */
1393
+ declare class AggregatorsResource {
1394
+ private readonly http;
1395
+ constructor(http: HTTPClient);
1396
+ /**
1397
+ * List all aggregator configurations for the current user.
1398
+ *
1399
+ * @returns Array of UserAggregator objects
1400
+ * @throws {AuthenticationError} If not authenticated
1401
+ *
1402
+ * @example
1403
+ * const aggregators = await client.users.aggregators.list();
1404
+ * for (const agg of aggregators) {
1405
+ * if (agg.isDefault) {
1406
+ * console.log(`Default: ${agg.name}`);
1407
+ * }
1408
+ * }
1409
+ */
1410
+ list(): Promise<UserAggregator[]>;
1411
+ /**
1412
+ * Get a specific aggregator configuration by ID.
1413
+ *
1414
+ * @param aggregatorId - The aggregator ID
1415
+ * @returns The UserAggregator object
1416
+ * @throws {AuthenticationError} If not authenticated
1417
+ * @throws {NotFoundError} If aggregator not found
1418
+ *
1419
+ * @example
1420
+ * const agg = await client.users.aggregators.get(1);
1421
+ * console.log(`${agg.name}: ${agg.url}`);
1422
+ */
1423
+ get(aggregatorId: number): Promise<UserAggregator>;
1424
+ /**
1425
+ * Create a new aggregator configuration.
1426
+ *
1427
+ * The first aggregator created is automatically set as the default.
1428
+ *
1429
+ * @param input - Aggregator creation input
1430
+ * @returns The created UserAggregator object
1431
+ * @throws {AuthenticationError} If not authenticated
1432
+ * @throws {ValidationError} If input is invalid
1433
+ *
1434
+ * @example
1435
+ * const agg = await client.users.aggregators.create({
1436
+ * name: 'My Custom Aggregator',
1437
+ * url: 'https://my-aggregator.example.com'
1438
+ * });
1439
+ * console.log(`Created: ${agg.id}`);
1440
+ */
1441
+ create(input: UserAggregatorCreateInput): Promise<UserAggregator>;
1442
+ /**
1443
+ * Update an aggregator configuration.
1444
+ *
1445
+ * Only provided fields will be updated.
1446
+ *
1447
+ * @param aggregatorId - The aggregator ID to update
1448
+ * @param input - Fields to update
1449
+ * @returns The updated UserAggregator object
1450
+ * @throws {AuthenticationError} If not authenticated
1451
+ * @throws {NotFoundError} If aggregator not found
1452
+ * @throws {ValidationError} If input is invalid
1453
+ *
1454
+ * @example
1455
+ * const agg = await client.users.aggregators.update(1, {
1456
+ * name: 'Updated Name'
1457
+ * });
1458
+ */
1459
+ update(aggregatorId: number, input: UserAggregatorUpdateInput): Promise<UserAggregator>;
1460
+ /**
1461
+ * Delete an aggregator configuration.
1462
+ *
1463
+ * @param aggregatorId - The aggregator ID to delete
1464
+ * @throws {AuthenticationError} If not authenticated
1465
+ * @throws {NotFoundError} If aggregator not found
1466
+ *
1467
+ * @example
1468
+ * await client.users.aggregators.delete(1);
1469
+ */
1470
+ delete(aggregatorId: number): Promise<void>;
938
1471
  /**
939
- * Get transaction tokens for multiple endpoint owners.
940
- *
941
- * Transaction tokens are short-lived JWTs that pre-authorize the endpoint owner
942
- * (recipient) to charge the current user (sender) for usage. These tokens are
943
- * created via the accounting service and passed to the aggregator.
1472
+ * Set an aggregator as the default.
944
1473
  *
945
- * This is used by the chat flow to enable billing for endpoint usage.
1474
+ * Only one aggregator can be the default at a time. Setting a new default
1475
+ * automatically unsets the previous one.
946
1476
  *
947
- * @param ownerUsernames - Array of endpoint owner usernames
948
- * @returns TransactionTokensResponse with tokens map and any errors
1477
+ * @param aggregatorId - The aggregator ID to set as default
1478
+ * @returns The updated UserAggregator object with isDefault=true
949
1479
  * @throws {AuthenticationError} If not authenticated
1480
+ * @throws {NotFoundError} If aggregator not found
950
1481
  *
951
1482
  * @example
952
- * // Get transaction tokens for endpoint owners
953
- * const response = await client.auth.getTransactionTokens(['alice', 'bob']);
954
- * console.log(`Got ${Object.keys(response.tokens).length} tokens`);
955
- * if (Object.keys(response.errors).length > 0) {
956
- * console.log('Some tokens failed:', response.errors);
957
- * }
1483
+ * const agg = await client.users.aggregators.setDefault(2);
1484
+ * console.log(`${agg.name} is now the default`);
958
1485
  */
959
- getTransactionTokens(ownerUsernames: string[]): Promise<TransactionTokensResponse>;
960
- }
961
- /**
962
- * Response from satellite token endpoint.
963
- */
964
- interface SatelliteTokenResponse {
965
- /** RS256-signed JWT for the target service */
966
- targetToken: string;
967
- /** Seconds until the token expires */
968
- expiresIn: number;
969
- }
970
- /**
971
- * Response from transaction tokens endpoint.
972
- */
973
- interface TransactionTokensResponse {
974
- /** Mapping of owner_username to transaction token */
975
- tokens: Record<string, string>;
976
- /** Mapping of owner_username to error message (for failed tokens) */
977
- errors: Record<string, string>;
1486
+ setDefault(aggregatorId: number): Promise<UserAggregator>;
978
1487
  }
979
1488
 
980
1489
  /**
@@ -994,10 +1503,41 @@ interface TransactionTokensResponse {
994
1503
  * @example
995
1504
  * // Check if email is available
996
1505
  * const available = await client.users.checkEmail('new@example.com');
1506
+ *
1507
+ * @example
1508
+ * // Manage aggregators
1509
+ * const aggregators = await client.users.aggregators.list();
1510
+ * const newAgg = await client.users.aggregators.create({
1511
+ * name: 'My Aggregator',
1512
+ * url: 'https://my-aggregator.example.com'
1513
+ * });
997
1514
  */
998
1515
  declare class UsersResource {
999
1516
  private readonly http;
1517
+ private _aggregators?;
1000
1518
  constructor(http: HTTPClient);
1519
+ /**
1520
+ * Access aggregator management operations.
1521
+ *
1522
+ * @returns AggregatorsResource for managing user's aggregator configurations
1523
+ *
1524
+ * @example
1525
+ * // List aggregators
1526
+ * const aggregators = await client.users.aggregators.list();
1527
+ * for (const agg of aggregators) {
1528
+ * console.log(`${agg.name}: ${agg.url}`);
1529
+ * }
1530
+ *
1531
+ * // Create aggregator
1532
+ * const agg = await client.users.aggregators.create({
1533
+ * name: 'My Aggregator',
1534
+ * url: 'https://my-aggregator.example.com'
1535
+ * });
1536
+ *
1537
+ * // Set as default
1538
+ * await client.users.aggregators.setDefault(agg.id);
1539
+ */
1540
+ get aggregators(): AggregatorsResource;
1001
1541
  /**
1002
1542
  * Update the current user's profile.
1003
1543
  *
@@ -1039,6 +1579,38 @@ declare class UsersResource {
1039
1579
  * }
1040
1580
  */
1041
1581
  getAccountingCredentials(): Promise<AccountingCredentials>;
1582
+ /**
1583
+ * Send a heartbeat to indicate this SyftAI Space is alive.
1584
+ *
1585
+ * The heartbeat mechanism allows SyftAI Spaces to signal their availability
1586
+ * to SyftHub. This should be called periodically (before the TTL expires)
1587
+ * to maintain the "active" status.
1588
+ *
1589
+ * @param input - Heartbeat parameters
1590
+ * @param input.url - Full URL of this space (e.g., "https://myspace.example.com").
1591
+ * The server extracts the domain from this URL.
1592
+ * @param input.ttlSeconds - Time-to-live in seconds (1-3600). The server caps this
1593
+ * at a maximum of 600 seconds (10 minutes). Default is 300
1594
+ * seconds (5 minutes).
1595
+ * @returns HeartbeatResponse containing status, expiry time, domain, and effective TTL
1596
+ * @throws {AuthenticationError} If not authenticated
1597
+ * @throws {ValidationError} If URL or TTL is invalid
1598
+ *
1599
+ * @example
1600
+ * // Send heartbeat with default TTL (300 seconds)
1601
+ * const response = await client.users.sendHeartbeat({
1602
+ * url: 'https://myspace.example.com'
1603
+ * });
1604
+ * console.log(`Next heartbeat before: ${response.expiresAt}`);
1605
+ *
1606
+ * @example
1607
+ * // Send heartbeat with custom TTL
1608
+ * const response = await client.users.sendHeartbeat({
1609
+ * url: 'https://myspace.example.com',
1610
+ * ttlSeconds: 600 // Maximum allowed
1611
+ * });
1612
+ */
1613
+ sendHeartbeat(input: HeartbeatInput): Promise<HeartbeatResponse>;
1042
1614
  }
1043
1615
 
1044
1616
  /**
@@ -1178,12 +1750,11 @@ declare class MyEndpointsResource {
1178
1750
  * Create a new endpoint.
1179
1751
  *
1180
1752
  * @param input - Endpoint creation details
1181
- * @param organizationId - Optional organization ID (for org-owned endpoints)
1182
1753
  * @returns The created Endpoint
1183
1754
  * @throws {AuthenticationError} If not authenticated
1184
1755
  * @throws {ValidationError} If input validation fails
1185
1756
  */
1186
- create(input: EndpointCreateInput, organizationId?: number): Promise<Endpoint>;
1757
+ create(input: EndpointCreateInput): Promise<Endpoint>;
1187
1758
  /**
1188
1759
  * Get a specific endpoint by path.
1189
1760
  *
@@ -1225,7 +1796,6 @@ declare class MyEndpointsResource {
1225
1796
  * 3. Is ATOMIC: either all endpoints sync successfully, or none do
1226
1797
  *
1227
1798
  * Important Notes:
1228
- * - Organization endpoints are NOT affected
1229
1799
  * - Stars on existing endpoints will be lost (reset to 0)
1230
1800
  * - Endpoint IDs will change (new IDs assigned)
1231
1801
  * - Maximum 100 endpoints per sync request
@@ -1256,6 +1826,8 @@ declare class MyEndpointsResource {
1256
1826
  * Options for browsing endpoints.
1257
1827
  */
1258
1828
  interface BrowseOptions {
1829
+ /** Filter by endpoint type ('model' or 'data_source') */
1830
+ endpointType?: string;
1259
1831
  /** Number of items per page (default: 20) */
1260
1832
  pageSize?: number;
1261
1833
  }
@@ -1263,11 +1835,22 @@ interface BrowseOptions {
1263
1835
  * Options for trending endpoints.
1264
1836
  */
1265
1837
  interface TrendingOptions {
1838
+ /** Filter by endpoint type ('model' or 'data_source') */
1839
+ endpointType?: string;
1266
1840
  /** Minimum number of stars */
1267
1841
  minStars?: number;
1268
1842
  /** Number of items per page (default: 20) */
1269
1843
  pageSize?: number;
1270
1844
  }
1845
+ /**
1846
+ * Options for listing guest-accessible endpoints.
1847
+ */
1848
+ interface GuestAccessibleOptions {
1849
+ /** Filter by endpoint type ('model' or 'data_source') */
1850
+ endpointType?: string;
1851
+ /** Number of items per page (default: 20) */
1852
+ pageSize?: number;
1853
+ }
1271
1854
  /**
1272
1855
  * Hub resource for browsing and discovering public endpoints.
1273
1856
  *
@@ -1327,8 +1910,12 @@ declare class HubResource {
1327
1910
  /**
1328
1911
  * Browse all public endpoints.
1329
1912
  *
1330
- * @param options - Pagination options
1913
+ * @param options - Filter and pagination options
1331
1914
  * @returns PageIterator that lazily fetches endpoints
1915
+ *
1916
+ * @example
1917
+ * // Browse only model endpoints
1918
+ * const models = await client.hub.browse({ endpointType: 'model' }).firstPage();
1332
1919
  */
1333
1920
  browse(options?: BrowseOptions): PageIterator<EndpointPublic>;
1334
1921
  /**
@@ -1336,8 +1923,32 @@ declare class HubResource {
1336
1923
  *
1337
1924
  * @param options - Filter and pagination options
1338
1925
  * @returns PageIterator that lazily fetches endpoints
1926
+ *
1927
+ * @example
1928
+ * // Get trending models only
1929
+ * const models = await client.hub.trending({ endpointType: 'model' }).firstPage();
1339
1930
  */
1340
1931
  trending(options?: TrendingOptions): PageIterator<EndpointPublic>;
1932
+ /**
1933
+ * List endpoints accessible to unauthenticated (guest) users.
1934
+ *
1935
+ * Guest-accessible endpoints are public, active, and have no policies attached.
1936
+ * No authentication is required to call this method.
1937
+ *
1938
+ * @param options - Filter and pagination options
1939
+ * @returns PageIterator that lazily fetches guest-accessible endpoints
1940
+ *
1941
+ * @example
1942
+ * // List all guest-accessible endpoints
1943
+ * for await (const endpoint of client.hub.guestAccessible()) {
1944
+ * console.log(`${endpoint.ownerUsername}/${endpoint.slug}: ${endpoint.name}`);
1945
+ * }
1946
+ *
1947
+ * @example
1948
+ * // List only guest-accessible models
1949
+ * const models = await client.hub.guestAccessible({ endpointType: 'model' }).firstPage();
1950
+ */
1951
+ guestAccessible(options?: GuestAccessibleOptions): PageIterator<EndpointPublic>;
1341
1952
  /**
1342
1953
  * Search for endpoints using semantic search.
1343
1954
  *
@@ -1394,6 +2005,22 @@ declare class HubResource {
1394
2005
  * @throws {NotFoundError} If endpoint not found
1395
2006
  */
1396
2007
  unstar(path: string): Promise<void>;
2008
+ /**
2009
+ * Get the owner/slug paths of a collective's approved member endpoints,
2010
+ * optionally narrowed to a single shared-endpoint subset.
2011
+ *
2012
+ * Used by the chat resource to expand both `collective/<slug>` and
2013
+ * `collective/<slug>/<shared-slug>` data-source references into the
2014
+ * individual endpoint paths before building the aggregator request.
2015
+ *
2016
+ * @param slug - The collective slug (e.g. "genomics-research")
2017
+ * @param sharedSlug - Optional curated-subset slug. When provided, only the
2018
+ * intersection of the subset's configured endpoints with the collective's
2019
+ * currently approved members is returned. Omit for "all approved members".
2020
+ * @returns Array of "owner/slug" path strings
2021
+ * @throws {NotFoundError} If the collective (or shared endpoint) does not exist
2022
+ */
2023
+ getCollectiveEndpointPaths(slug: string, sharedSlug?: string): Promise<string[]>;
1397
2024
  /**
1398
2025
  * Check if you have starred an endpoint.
1399
2026
  *
@@ -1406,295 +2033,176 @@ declare class HubResource {
1406
2033
  }
1407
2034
 
1408
2035
  /**
1409
- * Accounting Resource for SyftHub SDK
2036
+ * Accounting Resource for SyftHub SDK (MPP Wallet)
1410
2037
  *
1411
- * This module connects to an external accounting/billing service for managing
1412
- * user balances and transactions. The accounting service is separate from SyftHub
1413
- * and uses its own authentication (Basic auth with email/password).
2038
+ * This module provides wallet management operations via the SyftHub API.
2039
+ * Payments are handled through the MPP (Micropayment Protocol) 402 flow,
2040
+ * replacing the previous external accounting service with direct wallet support.
1414
2041
  *
1415
2042
  * @example
1416
2043
  * ```typescript
1417
- * // Create accounting client
1418
- * const accounting = new AccountingResource({
1419
- * url: 'https://accounting.example.com',
1420
- * email: 'user@example.com',
1421
- * password: 'secret'
1422
- * });
1423
- *
1424
- * // Get user balance
1425
- * const user = await accounting.getUser();
1426
- * console.log(`Balance: ${user.balance}`);
1427
- *
1428
- * // Create a transaction
1429
- * const tx = await accounting.createTransaction({
1430
- * recipientEmail: 'recipient@example.com',
1431
- * amount: 10.0,
1432
- * appName: 'syftai-space',
1433
- * appEpPath: 'alice/my-model'
1434
- * });
1435
- *
1436
- * // Confirm the transaction
1437
- * await accounting.confirmTransaction(tx.id);
2044
+ * // Initialize via client (after login)
2045
+ * await client.auth.login('alice', 'password');
2046
+ * await client.initAccounting();
2047
+ *
2048
+ * // Get wallet info
2049
+ * const wallet = await client.accounting.getWallet();
2050
+ * console.log(`Wallet address: ${wallet.address}`);
2051
+ *
2052
+ * // Get balance
2053
+ * const balance = await client.accounting.getBalance();
2054
+ * console.log(`Balance: ${balance.balance} ${balance.currency}`);
2055
+ *
2056
+ * // Get transactions
2057
+ * const transactions = await client.accounting.getTransactions();
2058
+ * for (const tx of transactions) {
2059
+ * console.log(`${tx.created_at}: ${tx.amount} from ${tx.sender_email}`);
2060
+ * }
1438
2061
  * ```
1439
2062
  */
1440
2063
 
1441
2064
  /**
1442
2065
  * Options for creating an AccountingResource.
2066
+ *
2067
+ * @deprecated The old AccountingResourceOptions with external service credentials
2068
+ * are no longer needed. Use the HTTPClient-based constructor instead.
1443
2069
  */
1444
2070
  interface AccountingResourceOptions {
1445
- /** Accounting service URL */
2071
+ /** @deprecated No longer used - wallet API is accessed via SyftHub */
1446
2072
  url: string;
1447
- /** Email for Basic auth */
2073
+ /** @deprecated No longer used */
1448
2074
  email: string;
1449
- /** Password for Basic auth */
2075
+ /** @deprecated No longer used */
1450
2076
  password: string;
1451
- /** Request timeout in milliseconds (default: 30000) */
2077
+ /** @deprecated No longer used */
1452
2078
  timeout?: number;
1453
2079
  }
1454
2080
  /**
1455
2081
  * Options for listing transactions.
2082
+ *
2083
+ * @deprecated Use getTransactions() which returns all transactions directly.
1456
2084
  */
1457
2085
  interface TransactionsOptions {
1458
2086
  /** Number of items per page (default: 20) */
1459
2087
  pageSize?: number;
1460
2088
  }
1461
2089
  /**
1462
- * Handle accounting/billing operations with external service.
2090
+ * Wallet and payment operations via the SyftHub API.
1463
2091
  *
1464
- * The accounting service manages user balances and transactions. It uses
1465
- * Basic auth (email/password) for authentication, which is separate from
1466
- * SyftHub's JWT-based authentication.
2092
+ * Manages MPP (Micropayment Protocol) wallets for users. Payments for
2093
+ * endpoint usage are handled automatically via the 402 payment flow
2094
+ * between the aggregator and SyftAI-Space instances.
1467
2095
  *
1468
- * Transaction Workflow:
1469
- * 1. Sender creates transaction (status=PENDING)
1470
- * 2. Either party confirms (status=COMPLETED) or cancels (status=CANCELLED)
2096
+ * @example
2097
+ * ```typescript
2098
+ * // Get wallet info
2099
+ * const wallet = await client.accounting.getWallet();
2100
+ * if (!wallet.exists) {
2101
+ * // Create a new wallet
2102
+ * const result = await client.accounting.createWallet();
2103
+ * console.log(`Created wallet: ${result.address}`);
2104
+ * }
1471
2105
  *
1472
- * Delegated Transaction Workflow:
1473
- * 1. Sender creates a transaction token for recipient
1474
- * 2. Recipient uses token to create delegated transaction
1475
- * 3. Recipient confirms the transaction
2106
+ * // Check balance
2107
+ * const balance = await client.accounting.getBalance();
2108
+ * console.log(`Balance: ${balance.balance} ${balance.currency}`);
2109
+ * ```
1476
2110
  */
1477
2111
  declare class AccountingResource {
1478
- private readonly baseUrl;
1479
- private readonly email;
1480
- private readonly password;
1481
- private readonly timeout;
1482
- private readonly authHeader;
1483
- constructor(options: AccountingResourceOptions);
1484
- /**
1485
- * Make an authenticated request to the accounting service.
1486
- */
1487
- private request;
1488
- /**
1489
- * Make a request using Bearer token auth (for delegated transactions).
1490
- */
1491
- private requestWithToken;
1492
- /**
1493
- * Get the current user's account information including balance.
1494
- *
1495
- * @returns AccountingUser with id, email, balance, and organization
1496
- * @throws {AuthenticationError} If authentication fails
1497
- * @throws {APIError} On other errors
1498
- *
1499
- * @example
1500
- * ```typescript
1501
- * const user = await accounting.getUser();
1502
- * console.log(`Balance: ${user.balance}`);
1503
- * console.log(`Organization: ${user.organization}`);
1504
- * ```
1505
- */
1506
- getUser(): Promise<AccountingUser>;
1507
- /**
1508
- * Update the user's password.
1509
- *
1510
- * @param currentPassword - Current password for verification
1511
- * @param newPassword - New password to set
1512
- * @throws {AuthenticationError} If current password is wrong
1513
- * @throws {ValidationError} If new password doesn't meet requirements
1514
- *
1515
- * @example
1516
- * ```typescript
1517
- * await accounting.updatePassword('old_secret', 'new_secret');
1518
- * ```
1519
- */
1520
- updatePassword(currentPassword: string, newPassword: string): Promise<void>;
1521
- /**
1522
- * Update the user's organization.
1523
- *
1524
- * @param organization - New organization name
1525
- * @throws {AuthenticationError} If authentication fails
1526
- *
1527
- * @example
1528
- * ```typescript
1529
- * await accounting.updateOrganization('OpenMined');
1530
- * ```
1531
- */
1532
- updateOrganization(organization: string): Promise<void>;
2112
+ private readonly http;
2113
+ constructor(http: HTTPClient);
1533
2114
  /**
1534
- * List account transactions with pagination.
2115
+ * Get the current user's wallet information.
1535
2116
  *
1536
- * Returns a lazy iterator that fetches pages on demand.
1537
- *
1538
- * @param options - Pagination options
1539
- * @returns PageIterator that yields Transaction objects
2117
+ * @returns WalletInfo with address and existence status
2118
+ * @throws {AuthenticationError} If not authenticated
1540
2119
  *
1541
2120
  * @example
1542
2121
  * ```typescript
1543
- * // Iterate through all transactions
1544
- * for await (const tx of accounting.getTransactions()) {
1545
- * console.log(`${tx.createdAt}: ${tx.amount} from ${tx.senderEmail}`);
2122
+ * const wallet = await client.accounting.getWallet();
2123
+ * if (wallet.exists) {
2124
+ * console.log(`Wallet address: ${wallet.address}`);
2125
+ * } else {
2126
+ * console.log('No wallet configured');
1546
2127
  * }
1547
- *
1548
- * // Get first page only
1549
- * const firstPage = await accounting.getTransactions().firstPage();
1550
- *
1551
- * // Get all transactions
1552
- * const allTxs = await accounting.getTransactions().all();
1553
- * ```
1554
- */
1555
- getTransactions(options?: TransactionsOptions): PageIterator<Transaction>;
1556
- /**
1557
- * Get a specific transaction by ID.
1558
- *
1559
- * @param transactionId - The transaction ID
1560
- * @returns Transaction object
1561
- * @throws {NotFoundError} If transaction not found
1562
- *
1563
- * @example
1564
- * ```typescript
1565
- * const tx = await accounting.getTransaction('tx_123');
1566
- * console.log(`Status: ${tx.status}`);
1567
- * ```
1568
- */
1569
- getTransaction(transactionId: string): Promise<Transaction>;
1570
- /**
1571
- * Create a new transaction (direct transfer).
1572
- *
1573
- * Creates a PENDING transaction that must be confirmed or cancelled.
1574
- * The transaction is created by the sender (current user).
1575
- *
1576
- * @param input - Transaction details
1577
- * @returns Transaction in PENDING status
1578
- * @throws {ValidationError} If amount <= 0 or insufficient balance
1579
- *
1580
- * @example
1581
- * ```typescript
1582
- * const tx = await accounting.createTransaction({
1583
- * recipientEmail: 'bob@example.com',
1584
- * amount: 10.0,
1585
- * appName: 'syftai-space',
1586
- * appEpPath: 'alice/my-model'
1587
- * });
1588
- * console.log(`Created transaction ${tx.id}: ${tx.status}`);
1589
- *
1590
- * // Later, confirm or cancel
1591
- * await accounting.confirmTransaction(tx.id);
1592
2128
  * ```
1593
2129
  */
1594
- createTransaction(input: CreateTransactionInput): Promise<Transaction>;
2130
+ getWallet(): Promise<WalletInfo>;
1595
2131
  /**
1596
- * Confirm a pending transaction.
1597
- *
1598
- * Confirms the transaction, transferring funds from sender to recipient.
1599
- * Can be called by either the sender or recipient.
2132
+ * Get the current user's wallet balance and recent transactions.
1600
2133
  *
1601
- * @param transactionId - The transaction ID to confirm
1602
- * @returns Transaction in COMPLETED status
1603
- * @throws {NotFoundError} If transaction not found
1604
- * @throws {ValidationError} If transaction is not in PENDING status
2134
+ * @returns WalletBalance with balance, currency, and recent transactions
2135
+ * @throws {AuthenticationError} If not authenticated
1605
2136
  *
1606
2137
  * @example
1607
2138
  * ```typescript
1608
- * const tx = await accounting.confirmTransaction('tx_123');
1609
- * console.log(`Confirmed: ${tx.status}`); // "completed"
2139
+ * const balance = await client.accounting.getBalance();
2140
+ * console.log(`Balance: ${balance.balance} ${balance.currency}`);
2141
+ * console.log(`Wallet configured: ${balance.wallet_configured}`);
1610
2142
  * ```
1611
2143
  */
1612
- confirmTransaction(transactionId: string): Promise<Transaction>;
2144
+ getBalance(): Promise<WalletBalance>;
1613
2145
  /**
1614
- * Cancel a pending transaction.
1615
- *
1616
- * Cancels the transaction without transferring funds.
1617
- * Can be called by either the sender or recipient.
2146
+ * Get the current user's wallet transactions.
1618
2147
  *
1619
- * @param transactionId - The transaction ID to cancel
1620
- * @returns Transaction in CANCELLED status
1621
- * @throws {NotFoundError} If transaction not found
1622
- * @throws {ValidationError} If transaction is not in PENDING status
2148
+ * @returns Array of WalletTransaction objects
2149
+ * @throws {AuthenticationError} If not authenticated
1623
2150
  *
1624
2151
  * @example
1625
2152
  * ```typescript
1626
- * const tx = await accounting.cancelTransaction('tx_123');
1627
- * console.log(`Cancelled: ${tx.status}`); // "cancelled"
2153
+ * const transactions = await client.accounting.getTransactions();
2154
+ * for (const tx of transactions) {
2155
+ * console.log(`${tx.created_at}: ${tx.amount} ${tx.status}`);
2156
+ * }
1628
2157
  * ```
1629
2158
  */
1630
- cancelTransaction(transactionId: string): Promise<Transaction>;
2159
+ getTransactions(): Promise<WalletTransaction[]>;
1631
2160
  /**
1632
- * Create a transaction token for delegated transfers.
2161
+ * Create a new wallet for the current user.
1633
2162
  *
1634
- * Creates a JWT token that authorizes the recipient to create a
1635
- * transaction on behalf of the sender (current user). The token
1636
- * is short-lived (typically ~5 minutes).
2163
+ * Generates a new wallet with a fresh keypair. The wallet address
2164
+ * is returned and stored on the server.
1637
2165
  *
1638
- * Use this when you want to pre-authorize a payment that will be
1639
- * initiated by the recipient (e.g., a service charging for usage).
1640
- *
1641
- * @param recipientEmail - Email of the authorized recipient
1642
- * @returns JWT token string to share with recipient
2166
+ * @returns Object with the new wallet address
2167
+ * @throws {AuthenticationError} If not authenticated
2168
+ * @throws {ValidationError} If user already has a wallet
1643
2169
  *
1644
2170
  * @example
1645
2171
  * ```typescript
1646
- * // Sender creates token
1647
- * const token = await accounting.createTransactionToken('service@example.com');
1648
- *
1649
- * // Share token with recipient out-of-band
1650
- * // Recipient uses token to create delegated transaction
2172
+ * const result = await client.accounting.createWallet();
2173
+ * console.log(`New wallet address: ${result.address}`);
1651
2174
  * ```
1652
2175
  */
1653
- createTransactionToken(recipientEmail: string): Promise<string>;
2176
+ createWallet(): Promise<{
2177
+ address: string;
2178
+ }>;
1654
2179
  /**
1655
- * Create a delegated transaction using a pre-authorized token.
1656
- *
1657
- * Creates a transaction on behalf of the sender using their token.
1658
- * This is typically used by services to charge users for usage.
2180
+ * Import an existing wallet using a private key.
1659
2181
  *
1660
- * The token authenticates the request instead of Basic auth.
1661
- *
1662
- * @param senderEmail - Email of the sender who created the token
1663
- * @param amount - Amount to transfer (must be > 0)
1664
- * @param token - JWT token from sender's createTransactionToken()
1665
- * @returns Transaction in PENDING status (createdBy=RECIPIENT)
1666
- * @throws {AuthenticationError} If token is invalid or expired
1667
- * @throws {ValidationError} If amount <= 0
2182
+ * @param privateKey - The private key to import
2183
+ * @returns Object with the imported wallet address
2184
+ * @throws {AuthenticationError} If not authenticated
2185
+ * @throws {ValidationError} If the private key is invalid
1668
2186
  *
1669
2187
  * @example
1670
2188
  * ```typescript
1671
- * // Recipient creates transaction using sender's token
1672
- * const tx = await accounting.createDelegatedTransaction(
1673
- * 'alice@example.com',
1674
- * 5.0,
1675
- * aliceToken
1676
- * );
1677
- *
1678
- * // Recipient confirms the transaction
1679
- * await accounting.confirmTransaction(tx.id);
2189
+ * const result = await client.accounting.importWallet('0x...');
2190
+ * console.log(`Imported wallet address: ${result.address}`);
1680
2191
  * ```
1681
2192
  */
1682
- createDelegatedTransaction(senderEmail: string, amount: number, token: string): Promise<Transaction>;
2193
+ importWallet(privateKey: string): Promise<{
2194
+ address: string;
2195
+ }>;
1683
2196
  }
1684
2197
  /**
1685
2198
  * Create a new AccountingResource instance.
1686
2199
  *
1687
- * @param options - Configuration options
1688
- * @returns AccountingResource instance
2200
+ * @deprecated Use the SyftHubClient's built-in accounting resource instead.
2201
+ * The wallet API is now accessed through the SyftHub HTTP client, not
2202
+ * a separate external service.
1689
2203
  *
1690
- * @example
1691
- * ```typescript
1692
- * const accounting = createAccountingResource({
1693
- * url: process.env.ACCOUNTING_URL!,
1694
- * email: process.env.ACCOUNTING_EMAIL!,
1695
- * password: process.env.ACCOUNTING_PASSWORD!
1696
- * });
1697
- * ```
2204
+ * @param options - Configuration options (ignored, kept for backward compatibility)
2205
+ * @returns AccountingResource instance
1698
2206
  */
1699
2207
  declare function createAccountingResource(options: AccountingResourceOptions): AccountingResource;
1700
2208
 
@@ -1823,6 +2331,225 @@ declare class AccountingServiceUnavailableError extends SyftHubError {
1823
2331
  constructor(message?: string, detail?: unknown | undefined);
1824
2332
  }
1825
2333
 
2334
+ /**
2335
+ * TypeScript type definitions for agent events, session state, and message payloads.
2336
+ */
2337
+ /**
2338
+ * Agent session state machine states.
2339
+ */
2340
+ type AgentSessionState = 'idle' | 'connecting' | 'running' | 'awaiting_input' | 'completed' | 'failed' | 'cancelled' | 'error';
2341
+ interface ThinkingEvent {
2342
+ type: 'agent.thinking';
2343
+ payload: {
2344
+ content: string;
2345
+ is_streaming: boolean;
2346
+ };
2347
+ }
2348
+ interface ToolCallEvent {
2349
+ type: 'agent.tool_call';
2350
+ payload: {
2351
+ tool_call_id: string;
2352
+ tool_name: string;
2353
+ arguments: Record<string, unknown>;
2354
+ requires_confirmation: boolean;
2355
+ description?: string;
2356
+ };
2357
+ }
2358
+ interface ToolResultEvent {
2359
+ type: 'agent.tool_result';
2360
+ payload: {
2361
+ tool_call_id: string;
2362
+ status: 'success' | 'error';
2363
+ result?: unknown;
2364
+ error?: string;
2365
+ duration_ms?: number;
2366
+ };
2367
+ }
2368
+ interface AgentMessageEvent {
2369
+ type: 'agent.message';
2370
+ payload: {
2371
+ content: string;
2372
+ is_complete: boolean;
2373
+ };
2374
+ }
2375
+ interface TokenEvent {
2376
+ type: 'agent.token';
2377
+ payload: {
2378
+ token: string;
2379
+ };
2380
+ }
2381
+ interface StatusEvent {
2382
+ type: 'agent.status';
2383
+ payload: {
2384
+ status: string;
2385
+ detail: string;
2386
+ progress?: number;
2387
+ };
2388
+ }
2389
+ interface RequestInputEvent {
2390
+ type: 'agent.request_input';
2391
+ payload: {
2392
+ prompt: string;
2393
+ };
2394
+ }
2395
+ interface SessionCreatedEvent {
2396
+ type: 'session.created';
2397
+ payload: {
2398
+ session_id: string;
2399
+ };
2400
+ }
2401
+ interface SessionCompletedEvent {
2402
+ type: 'session.completed';
2403
+ payload: {
2404
+ session_id: string;
2405
+ };
2406
+ }
2407
+ interface SessionFailedEvent {
2408
+ type: 'session.failed';
2409
+ payload: {
2410
+ error: string;
2411
+ reason: string;
2412
+ };
2413
+ }
2414
+ interface AgentErrorEvent {
2415
+ type: 'agent.error';
2416
+ payload: {
2417
+ code: string;
2418
+ message: string;
2419
+ recoverable: boolean;
2420
+ };
2421
+ }
2422
+ /**
2423
+ * Union type of all possible agent events.
2424
+ */
2425
+ type AgentEvent = ThinkingEvent | ToolCallEvent | ToolResultEvent | AgentMessageEvent | TokenEvent | StatusEvent | RequestInputEvent | SessionCreatedEvent | SessionCompletedEvent | SessionFailedEvent | AgentErrorEvent;
2426
+ /**
2427
+ * Configuration for agent sessions.
2428
+ */
2429
+ interface AgentConfig {
2430
+ maxTokens?: number;
2431
+ temperature?: number;
2432
+ systemPrompt?: string;
2433
+ metadata?: Record<string, unknown>;
2434
+ }
2435
+ /**
2436
+ * Message in conversation history.
2437
+ */
2438
+ interface AgentHistoryMessage {
2439
+ role: string;
2440
+ content: string;
2441
+ }
2442
+ /**
2443
+ * Options for starting an agent session.
2444
+ */
2445
+ interface AgentSessionOptions {
2446
+ /** The initial prompt */
2447
+ prompt: string;
2448
+ /** Endpoint in "owner/slug" format or { owner, slug } object */
2449
+ endpoint: string | {
2450
+ owner: string;
2451
+ slug: string;
2452
+ };
2453
+ /** Optional agent configuration */
2454
+ config?: AgentConfig;
2455
+ /** Optional conversation history */
2456
+ messages?: AgentHistoryMessage[];
2457
+ /** Optional AbortSignal for cancellation */
2458
+ signal?: AbortSignal;
2459
+ }
2460
+
2461
+ /**
2462
+ * Agent resource for bidirectional agent sessions via WebSocket.
2463
+ *
2464
+ * @example
2465
+ * const session = await client.agent.startSession({
2466
+ * prompt: 'Help me refactor this code',
2467
+ * endpoint: 'alice/code-assistant',
2468
+ * });
2469
+ *
2470
+ * for await (const event of session.events()) {
2471
+ * switch (event.type) {
2472
+ * case 'agent.message':
2473
+ * console.log(event.payload.content);
2474
+ * break;
2475
+ * case 'agent.tool_call':
2476
+ * if (event.payload.requires_confirmation) {
2477
+ * await session.confirm(event.payload.tool_call_id);
2478
+ * }
2479
+ * break;
2480
+ * }
2481
+ * }
2482
+ */
2483
+
2484
+ /**
2485
+ * Error thrown during agent session operations.
2486
+ */
2487
+ declare class AgentSessionError extends SyftHubError {
2488
+ readonly code?: string | undefined;
2489
+ constructor(message: string, code?: string | undefined);
2490
+ }
2491
+ /**
2492
+ * AgentResource manages agent session lifecycle.
2493
+ */
2494
+ declare class AgentResource {
2495
+ private readonly auth;
2496
+ private readonly aggregatorUrl;
2497
+ constructor(auth: AuthResource, aggregatorUrl: string);
2498
+ /**
2499
+ * Start a new agent session.
2500
+ *
2501
+ * @param options - Session options including prompt, endpoint, and config
2502
+ * @returns An AgentSessionClient for interacting with the session
2503
+ */
2504
+ startSession(options: AgentSessionOptions): Promise<AgentSessionClient>;
2505
+ }
2506
+ /**
2507
+ * Client for an active agent session.
2508
+ * Provides both async iterable and callback-based APIs for receiving events.
2509
+ */
2510
+ declare class AgentSessionClient {
2511
+ private readonly ws;
2512
+ readonly sessionId: string;
2513
+ private _state;
2514
+ private _sequenceCounter;
2515
+ private _messageQueue;
2516
+ private _messageResolvers;
2517
+ private _closed;
2518
+ constructor(ws: WebSocket, sessionId: string);
2519
+ /** Current session state */
2520
+ get state(): AgentSessionState;
2521
+ /**
2522
+ * Async generator yielding agent events.
2523
+ *
2524
+ * @example
2525
+ * for await (const event of session.events()) {
2526
+ * console.log(event.type, event.payload);
2527
+ * }
2528
+ */
2529
+ events(): AsyncGenerator<AgentEvent>;
2530
+ /**
2531
+ * Register an event handler.
2532
+ *
2533
+ * @param eventType - The event type to listen for, or '*' for all events
2534
+ * @param handler - Callback function
2535
+ */
2536
+ on(eventType: string, handler: (event: AgentEvent) => void): void;
2537
+ /** Send a user message to the agent */
2538
+ sendMessage(content: string): void;
2539
+ /** Confirm a tool call */
2540
+ confirm(toolCallId: string): void;
2541
+ /** Deny a tool call */
2542
+ deny(toolCallId: string, reason?: string): void;
2543
+ /** Cancel the session */
2544
+ cancel(): void;
2545
+ /** Close the session and WebSocket */
2546
+ close(): void;
2547
+ private _send;
2548
+ private _handleMessage;
2549
+ private _handleClose;
2550
+ private _nextEvent;
2551
+ }
2552
+
1826
2553
  /**
1827
2554
  * Chat resource for RAG-augmented conversations via the Aggregator service.
1828
2555
  *
@@ -1876,6 +2603,11 @@ declare class ChatResource {
1876
2603
  private readonly auth;
1877
2604
  private readonly aggregatorUrl;
1878
2605
  constructor(hub: HubResource, auth: AuthResource, aggregatorUrl: string);
2606
+ /**
2607
+ * Check if an endpoint type matches the expected type.
2608
+ * A model_data_source endpoint matches both 'model' and 'data_source'.
2609
+ */
2610
+ private static typeMatches;
1879
2611
  /**
1880
2612
  * Convert any endpoint format to EndpointRef with URL and owner info.
1881
2613
  * The ownerUsername is critical for satellite token authentication.
@@ -1889,16 +2621,16 @@ declare class ChatResource {
1889
2621
  /**
1890
2622
  * Get satellite tokens for all unique endpoint owners.
1891
2623
  * Returns a map of owner username to satellite token.
2624
+ *
2625
+ * @param owners - Array of unique owner usernames
2626
+ * @param guestMode - If true, fetch guest tokens (no auth required)
1892
2627
  */
1893
2628
  private getSatelliteTokensForOwners;
1894
2629
  /**
1895
- * Get transaction tokens for all unique endpoint owners.
1896
- * Returns a map of owner username to transaction token.
1897
- *
1898
- * Transaction tokens are used for billing - they authorize the endpoint
1899
- * owner to charge the current user for usage.
2630
+ * Get the user's Hub access token for MPP payment flow.
2631
+ * Returns null if in guest mode or not authenticated.
1900
2632
  */
1901
- private getTransactionTokensForOwners;
2633
+ private getUserToken;
1902
2634
  /**
1903
2635
  * Type guard for EndpointRef.
1904
2636
  */
@@ -1907,10 +2639,42 @@ declare class ChatResource {
1907
2639
  * Type guard for EndpointPublic.
1908
2640
  */
1909
2641
  private isEndpointPublic;
2642
+ private static readonly COLLECTIVE_PREFIX;
2643
+ private static readonly TUNNELING_PREFIX;
2644
+ /**
2645
+ * Expand any `collective/<slug>` (or `collective/<slug>/<shared-slug>`)
2646
+ * entries in the data-sources list into the individual `owner/slug` paths
2647
+ * of the collective's approved members.
2648
+ *
2649
+ * Path forms recognised:
2650
+ * - `collective/<slug>` → every approved member (backward-compatible)
2651
+ * - `collective/<slug>/all` → equivalent alias of the above
2652
+ * - `collective/<slug>/<shared-slug>` → the named subset, intersected with
2653
+ * the collective's currently approved members
2654
+ *
2655
+ * Non-collective entries pass through unchanged. String paths are
2656
+ * deduplicated so a regular endpoint that also belongs to a selected
2657
+ * collective is not queried twice.
2658
+ */
2659
+ private expandCollectivePaths;
2660
+ /**
2661
+ * Check if any endpoints use tunneling URLs and extract target usernames.
2662
+ */
2663
+ private collectTunnelingUsernames;
2664
+ /**
2665
+ * Shared request preparation for complete() and stream().
2666
+ * Resolves endpoints, fetches tokens, and builds the aggregator request body.
2667
+ * Returns the request body and the resolved aggregator URL.
2668
+ */
2669
+ private prepareRequest;
2670
+ /**
2671
+ * Parse an error response from the aggregator into an AggregatorError.
2672
+ */
2673
+ private handleAggregatorErrorResponse;
1910
2674
  /**
1911
2675
  * Build the request body for the aggregator.
1912
2676
  * Includes endpoint_tokens mapping for satellite token authentication.
1913
- * Includes transaction_tokens mapping for billing authorization.
2677
+ * Includes user_token for MPP payment callback authorization.
1914
2678
  * User identity is derived from satellite tokens, not passed in request body.
1915
2679
  */
1916
2680
  private buildRequestBody;
@@ -1941,7 +2705,7 @@ declare class ChatResource {
1941
2705
  * This method automatically:
1942
2706
  * 1. Resolves endpoints and extracts owner information
1943
2707
  * 2. Exchanges Hub tokens for satellite tokens (one per unique owner)
1944
- * 3. Fetches transaction tokens for billing authorization
2708
+ * 3. Passes the user's Hub access token for MPP payment authorization
1945
2709
  * 4. Sends tokens to the aggregator for forwarding to SyftAI-Space
1946
2710
  *
1947
2711
  * @param options - Chat completion options
@@ -1956,7 +2720,7 @@ declare class ChatResource {
1956
2720
  * This method automatically:
1957
2721
  * 1. Resolves endpoints and extracts owner information
1958
2722
  * 2. Exchanges Hub tokens for satellite tokens (one per unique owner)
1959
- * 3. Fetches transaction tokens for billing authorization
2723
+ * 3. Passes the user's Hub access token for MPP payment authorization
1960
2724
  * 4. Sends tokens to the aggregator for forwarding to SyftAI-Space
1961
2725
  *
1962
2726
  * @param options - Chat completion options
@@ -1967,6 +2731,7 @@ declare class ChatResource {
1967
2731
  * Parse an SSE event into a typed event object.
1968
2732
  */
1969
2733
  private parseSSEEvent;
2734
+ private getAvailableEndpoints;
1970
2735
  /**
1971
2736
  * Get model endpoints that have connection URLs configured.
1972
2737
  *
@@ -2036,13 +2801,50 @@ declare class GenerationError extends SyftHubError {
2036
2801
  * For most use cases, prefer the higher-level `client.chat` API instead.
2037
2802
  */
2038
2803
  declare class SyftAIResource {
2804
+ private readonly http;
2805
+ /**
2806
+ * @param http - Hub HTTP client, used to mint satellite tokens and settle
2807
+ * MPP payments. Endpoint queries themselves use direct `fetch`, since the
2808
+ * SyftAI-Space URL is arbitrary and not the Hub base URL.
2809
+ */
2810
+ constructor(http: HTTPClient);
2811
+ /**
2812
+ * Mint a satellite token for `audience` (the endpoint owner's username).
2813
+ *
2814
+ * Mirrors the aggregator's token coordination layer: try an authenticated
2815
+ * token first, then fall back to a guest token. Returns `undefined` if both
2816
+ * fail, so the caller can still attempt an unauthenticated request.
2817
+ */
2818
+ private mintSatelliteToken;
2819
+ /**
2820
+ * Pay an MPP `402` challenge via the Hub wallet, returning an X-Payment credential.
2821
+ *
2822
+ * Mirrors the aggregator's `handleMppPayment`: the `WWW-Authenticate`
2823
+ * challenge is forwarded verbatim to the Hub's `/api/v1/wallet/pay`, which
2824
+ * parses it and returns an `x_payment` string to attach to a retry.
2825
+ */
2826
+ private payMpp;
2039
2827
  /**
2040
2828
  * Build headers for SyftAI-Space request.
2041
2829
  */
2042
2830
  private buildHeaders;
2831
+ /**
2832
+ * Parse documents from a SyftAI-Space query response.
2833
+ *
2834
+ * Mirrors the aggregator's `DataSourceClient._parse_syftai_response`: the
2835
+ * canonical shape nests documents under `references.documents` and names the
2836
+ * score `similarity_score`. A legacy top-level `documents` list (with
2837
+ * `score`) is still honoured for backward compatibility.
2838
+ */
2839
+ private parseDocuments;
2043
2840
  /**
2044
2841
  * Query a data source endpoint directly.
2045
2842
  *
2843
+ * Authentication mirrors the aggregator: SyftAI-Space endpoints expect a
2844
+ * satellite bearer token whose audience is the endpoint owner's username. If
2845
+ * `authorizationToken` is not supplied, one is minted automatically when an
2846
+ * owner is known (`ownerUsername` option or `endpoint.ownerUsername`).
2847
+ *
2046
2848
  * @param options - Query options
2047
2849
  * @returns Array of Document objects
2048
2850
  * @throws {RetrievalError} If the query fails
@@ -2087,6 +2889,13 @@ interface SyftHubClientOptions {
2087
2889
  * Defaults to {baseUrl}/aggregator/api/v1
2088
2890
  */
2089
2891
  aggregatorUrl?: string;
2892
+ /**
2893
+ * API token for authentication (alternative to username/password login).
2894
+ * If provided, the client will be authenticated immediately without needing to call login().
2895
+ * Falls back to SYFTHUB_API_TOKEN environment variable.
2896
+ * @example 'syft_pat_xxxxx...'
2897
+ */
2898
+ apiToken?: string;
2090
2899
  }
2091
2900
  /**
2092
2901
  * SyftHub SDK client for interacting with the SyftHub API.
@@ -2133,16 +2942,16 @@ interface SyftHubClientOptions {
2133
2942
  */
2134
2943
  declare class SyftHubClient {
2135
2944
  private readonly http;
2136
- private readonly options;
2137
2945
  private readonly aggregatorUrl;
2138
2946
  private _auth?;
2139
2947
  private _users?;
2140
2948
  private _myEndpoints?;
2141
2949
  private _hub?;
2142
2950
  private _accounting?;
2143
- private _accountingInitPromise;
2951
+ private _agent?;
2144
2952
  private _chat?;
2145
2953
  private _syftai?;
2954
+ private _apiTokens?;
2146
2955
  /**
2147
2956
  * Create a new SyftHub client.
2148
2957
  *
@@ -2184,13 +2993,28 @@ declare class SyftHubClient {
2184
2993
  */
2185
2994
  get hub(): HubResource;
2186
2995
  /**
2187
- * Accounting resource for billing and transactions.
2996
+ * Agent resource for bidirectional agent sessions via WebSocket.
2997
+ *
2998
+ * @example
2999
+ * const session = await client.agent.startSession({
3000
+ * prompt: 'Help me refactor this code',
3001
+ * endpoint: 'alice/code-assistant',
3002
+ * });
3003
+ *
3004
+ * for await (const event of session.events()) {
3005
+ * console.log(event.type, event.payload);
3006
+ * }
3007
+ */
3008
+ get agent(): AgentResource;
3009
+ /**
3010
+ * Accounting resource for wallet and payment operations.
2188
3011
  *
2189
- * The accounting service is external and uses separate credentials
2190
- * (email/password Basic auth) from SyftHub's JWT authentication.
3012
+ * Provides access to MPP wallet management (balance, transactions,
3013
+ * wallet creation/import). Uses the same SyftHub JWT authentication
3014
+ * as other resources.
2191
3015
  *
2192
- * Credentials are automatically retrieved from the backend after login.
2193
- * You must call `initAccounting()` after login to initialize this resource.
3016
+ * You must call `initAccounting()` after login to initialize this resource,
3017
+ * or access it directly if already initialized.
2194
3018
  *
2195
3019
  * @throws {AuthenticationError} If not initialized
2196
3020
  *
@@ -2200,18 +3024,18 @@ declare class SyftHubClient {
2200
3024
  * await client.initAccounting();
2201
3025
  *
2202
3026
  * // Now accounting is available
2203
- * const user = await client.accounting.getUser();
3027
+ * const wallet = await client.accounting.getWallet();
3028
+ * const balance = await client.accounting.getBalance();
2204
3029
  */
2205
3030
  get accounting(): AccountingResource;
2206
3031
  /**
2207
- * Initialize accounting resource by fetching credentials from the backend.
3032
+ * Initialize the accounting (wallet) resource.
2208
3033
  *
2209
- * This method retrieves accounting credentials from the SyftHub backend
2210
- * and initializes the accounting resource. Requires authentication.
3034
+ * The wallet API uses the same SyftHub authentication as other resources.
3035
+ * This method simply verifies authentication and creates the resource.
2211
3036
  *
2212
3037
  * @returns The initialized AccountingResource
2213
3038
  * @throws {AuthenticationError} If not authenticated
2214
- * @throws {ConfigurationError} If user has no accounting service configured
2215
3039
  *
2216
3040
  * @example
2217
3041
  * // Login first, then initialize accounting
@@ -2219,13 +3043,10 @@ declare class SyftHubClient {
2219
3043
  * await client.initAccounting();
2220
3044
  *
2221
3045
  * // Now accounting is available
2222
- * const user = await client.accounting.getUser();
3046
+ * const wallet = await client.accounting.getWallet();
3047
+ * const balance = await client.accounting.getBalance();
2223
3048
  */
2224
3049
  initAccounting(): Promise<AccountingResource>;
2225
- /**
2226
- * Internal method to perform accounting initialization.
2227
- */
2228
- private _doInitAccounting;
2229
3050
  /**
2230
3051
  * Chat resource for RAG-augmented conversations via the Aggregator.
2231
3052
  *
@@ -2278,6 +3099,33 @@ declare class SyftHubClient {
2278
3099
  * });
2279
3100
  */
2280
3101
  get syftai(): SyftAIResource;
3102
+ /**
3103
+ * API Tokens resource for managing personal access tokens.
3104
+ *
3105
+ * API tokens provide an alternative to username/password authentication.
3106
+ * They are ideal for CI/CD pipelines, scripts, and programmatic access.
3107
+ *
3108
+ * @example
3109
+ * // Create a new token
3110
+ * const result = await client.apiTokens.create({
3111
+ * name: 'CI/CD Pipeline',
3112
+ * scopes: ['write'],
3113
+ * });
3114
+ * console.log('Save this token:', result.token);
3115
+ *
3116
+ * // List all tokens
3117
+ * const { tokens } = await client.apiTokens.list();
3118
+ *
3119
+ * // Revoke a token
3120
+ * await client.apiTokens.revoke(tokenId);
3121
+ */
3122
+ get apiTokens(): APITokensResource;
3123
+ /**
3124
+ * Check if the client is using API token authentication.
3125
+ *
3126
+ * @returns True if authenticated with an API token (vs JWT)
3127
+ */
3128
+ get isUsingApiToken(): boolean;
2281
3129
  /**
2282
3130
  * Get current authentication tokens.
2283
3131
  *
@@ -2313,7 +3161,7 @@ declare class SyftHubClient {
2313
3161
  */
2314
3162
  get isAuthenticated(): boolean;
2315
3163
  /**
2316
- * Check if accounting has been initialized.
3164
+ * Check if the accounting (wallet) resource has been initialized.
2317
3165
  *
2318
3166
  * Use this to check if accounting is available before accessing
2319
3167
  * the `accounting` property, which will throw if not initialized.
@@ -2322,7 +3170,7 @@ declare class SyftHubClient {
2322
3170
  *
2323
3171
  * @example
2324
3172
  * if (client.isAccountingInitialized) {
2325
- * const user = await client.accounting.getUser();
3173
+ * const wallet = await client.accounting.getWallet();
2326
3174
  * }
2327
3175
  */
2328
3176
  get isAccountingInitialized(): boolean;
@@ -2334,4 +3182,4 @@ declare class SyftHubClient {
2334
3182
  close(): void;
2335
3183
  }
2336
3184
 
2337
- 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 SyncEndpointsResponse, 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 };
3185
+ export { APIError, type APIToken, type APITokenCreateResponse, type APITokenListResponse, type APITokenScope, APITokensResource, AccountingAccountExistsError, type AccountingCredentials, AccountingResource, type AccountingResourceOptions, AccountingServiceUnavailableError, type AgentConfig, type AgentErrorEvent, type AgentEvent, type AgentHistoryMessage, type AgentMessageEvent, type RequestInputEvent as AgentRequestInputEvent, AgentResource, AgentSessionClient, type SessionCompletedEvent as AgentSessionCompletedEvent, type SessionCreatedEvent as AgentSessionCreatedEvent, AgentSessionError, type SessionFailedEvent as AgentSessionFailedEvent, type AgentSessionOptions, type AgentSessionState, type StatusEvent as AgentStatusEvent, type ThinkingEvent as AgentThinkingEvent, type TokenEvent as AgentTokenEvent, type ToolCallEvent as AgentToolCallEvent, type ToolResultEvent as AgentToolResultEvent, AggregatorError, AggregatorsResource, type AuthConfig, type AuthTokens, AuthenticationError, AuthorizationError, type BrowseOptions, type ChatMetadata, type ChatOptions, ChatResource, type ChatResponse, type ChatStreamEvent, ConfigurationError, type Connection, type CreateAPITokenInput, type Document, type DocumentSource, type DoneEvent, type Endpoint, type EndpointCreateInput, type EndpointPublic, type EndpointRef, EndpointResolutionError, EndpointType, type EndpointUpdateInput, type ErrorEvent, GenerationError, type GenerationStartEvent, type HeartbeatInput, type HeartbeatResponse, InvalidAccountingPasswordError, type ListEndpointsOptions, type Message, NetworkError, NotFoundError, type PageFetcher, PageIterator, type PasswordChangeInput, type PasswordResetConfirmInput, type PasswordResetRequestInput, type Policy, type QueryDataSourceOptions, type QueryModelOptions, type RegisterResult, type RetrievalCompleteEvent, RetrievalError, type RetrievalStartEvent, type SourceCompleteEvent, type SourceInfo, type SourceStatus, SyftAIResource, SyftHubClient, type SyftHubClientOptions, SyftHubError, type SyncEndpointsResponse, type TokenEvent$1 as TokenEvent, type TransactionTokensResponse, type TransactionsOptions, type TrendingOptions, type UpdateAPITokenInput, type User, type UserAggregator, type UserAggregatorCreateInput, type UserAggregatorUpdateInput, UserAlreadyExistsError, type UserRegisterInput, UserRole, type UserUpdateInput, ValidationError, type VerifyOTPInput, Visibility, type WalletBalance, type WalletInfo, type WalletTransaction, createAccountingResource, getEndpointPublicPath };