@syfthub/sdk 0.2.1 → 0.3.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.cts CHANGED
@@ -792,7 +792,15 @@ interface Document {
792
792
  /**
793
793
  * Status of a data source query.
794
794
  */
795
- type SourceStatus = 'success' | 'error' | 'timeout';
795
+ type SourceStatus = 'success' | 'error' | 'timeout' | 'payment_failed' | 'access_denied' | 'policy_violation' | 'rate_limited';
796
+ /**
797
+ * Machine-readable rejection reason on a {@link BillingEntry}.
798
+ *
799
+ * The known set the producer emits today. `BillingEntry.reasonCode` stays open
800
+ * (`ReasonCode | (string & {})`) so a future code never breaks typing, while
801
+ * still offering autocomplete on the known values.
802
+ */
803
+ type ReasonCode = 'NO_PRICING_TIER' | 'INSUFFICIENT_BALANCE' | 'PAYMENT_REQUIRED' | 'ACCESS_DENIED' | 'RATE_LIMITED';
796
804
  /**
797
805
  * Information about a data source retrieval (metadata).
798
806
  */
@@ -838,6 +846,101 @@ interface TokenUsage {
838
846
  /** Total tokens used */
839
847
  totalTokens: number;
840
848
  }
849
+ /**
850
+ * The "to whom" of a billing entry — the endpoint owner / publisher.
851
+ *
852
+ * All fields are optional; `walletAddress` is a public MPP address only and
853
+ * never a private key.
854
+ */
855
+ interface Recipient {
856
+ /** Endpoint owner / publisher username */
857
+ username?: string;
858
+ /** Recipient email */
859
+ email?: string;
860
+ /** Public MPP wallet address (never a private key) */
861
+ walletAddress?: string;
862
+ }
863
+ /**
864
+ * A rail-native transaction reference for a billing entry.
865
+ *
866
+ * `id` is the rail-native identifier (Tempo tx hash for `mpp`; the ledger
867
+ * transaction id for `xendit` / `stripe`); `rail` is the discriminator.
868
+ */
869
+ interface Transaction {
870
+ /** Payment rail discriminator (mpp, xendit, stripe, ...) */
871
+ rail: string;
872
+ /** Rail-native transaction id */
873
+ id: string;
874
+ /** Secondary reference (e.g. MPP external_id) */
875
+ reference?: string;
876
+ }
877
+ /**
878
+ * A single policy-metadata entry from a queried source.
879
+ *
880
+ * Emitted by both payment and non-payment policies. When surfaced via the
881
+ * aggregated {@link Billing} block, `source` carries the `owner/slug` of the
882
+ * source that produced the entry; on the direct path it is absent.
883
+ */
884
+ interface BillingEntry {
885
+ /** Source endpoint path (owner/slug); absent if direct */
886
+ source?: string;
887
+ /** Policy type (e.g. mpp_per_request, rate_limit, pii_filter) */
888
+ policyType: string;
889
+ /** Policy kind (payment, access, transform, rate_limit) */
890
+ kind: string;
891
+ /** Outcome status (charged, refunded, free, rejected, applied, skipped) */
892
+ status: string;
893
+ /** Charged amount, if any */
894
+ amount?: number;
895
+ /** Currency code, if any */
896
+ currency?: string;
897
+ /** Who the payment is owed to, if any */
898
+ recipient?: Recipient;
899
+ /** Rail-native transaction reference, if any */
900
+ transaction?: Transaction;
901
+ /** Machine-readable rejection code; see {@link ReasonCode} for the known set */
902
+ reasonCode?: ReasonCode | (string & {});
903
+ /** Human-readable reason message */
904
+ reason?: string;
905
+ /** Extra structured details (e.g. { documents: 3 }) */
906
+ details: Record<string, unknown>;
907
+ }
908
+ /**
909
+ * Aggregated billing block surfaced on chat and search responses.
910
+ *
911
+ * `totalCost` is the sum of entries with `status === "charged"` (null if none
912
+ * charged); `currency` is the common currency or null if mixed. No FX
913
+ * conversion is performed — each entry keeps its own currency.
914
+ */
915
+ interface Billing {
916
+ /**
917
+ * Sum of charged entries; null if nothing charged.
918
+ *
919
+ * Note: can be > 0 on a *rejected* query — an earlier policy may have
920
+ * committed a charge before a later policy blocked the request (the
921
+ * rejection carries both the `charged` and the `rejected` entry). Inspect
922
+ * per-entry `status` rather than assuming a positive `totalCost` means success.
923
+ */
924
+ totalCost: number | null;
925
+ /** Common currency, or null if mixed */
926
+ currency: string | null;
927
+ /** Per-source policy-metadata entries */
928
+ entries: BillingEntry[];
929
+ }
930
+ /**
931
+ * Raw policy-metadata block returned on the direct syft-space path.
932
+ *
933
+ * Unlike the aggregated {@link Billing} block, this is the per-source object
934
+ * exactly as the syft-space `/query` response carries it: an `outcome` string
935
+ * plus the list of {@link BillingEntry} items (whose `source` key is absent on
936
+ * the direct path). No aggregation or total is applied.
937
+ */
938
+ interface PolicyMetadata {
939
+ /** Query outcome (e.g. success, payment_required) */
940
+ outcome: string;
941
+ /** Per-policy metadata entries */
942
+ entries: BillingEntry[];
943
+ }
841
944
  /**
842
945
  * Response from a chat completion request.
843
946
  */
@@ -854,6 +957,8 @@ interface ChatResponse {
854
957
  usage?: TokenUsage;
855
958
  /** Normalized contribution scores per source (owner/slug to fraction 0-1) */
856
959
  profitShare?: Record<string, number>;
960
+ /** Aggregated payment-policy metadata across queried sources */
961
+ billing?: Billing;
857
962
  }
858
963
  /**
859
964
  * A chat message for model queries.
@@ -895,6 +1000,73 @@ interface ChatOptions {
895
1000
  /** Conversation history (prior turns) for multi-turn context */
896
1001
  messages?: Message[];
897
1002
  }
1003
+ /**
1004
+ * A single document returned by a retrieval-only search.
1005
+ *
1006
+ * Unlike {@link Document} (the low-level direct-query shape), this carries the
1007
+ * document title and the source endpoint path, matching the aggregated
1008
+ * `sources` map returned by the aggregator's retrieval-only path.
1009
+ */
1010
+ interface SearchDocument {
1011
+ /** Document title (key in the sources map) */
1012
+ title: string;
1013
+ /** Source endpoint path (owner/slug) the document came from */
1014
+ slug: string;
1015
+ /** The document content */
1016
+ content: string;
1017
+ }
1018
+ /**
1019
+ * Options for a retrieval-only search via the Aggregator.
1020
+ *
1021
+ * Symmetric to {@link ChatOptions} minus the model: data sources are queried
1022
+ * for relevant documents, but no model is invoked.
1023
+ */
1024
+ interface SearchQueryOptions {
1025
+ /** The search query */
1026
+ prompt: string;
1027
+ /** Data source endpoints (paths, EndpointRefs, or `collective/<slug>` paths) */
1028
+ dataSources?: (string | EndpointRef)[];
1029
+ /** Number of documents to retrieve per source (default: 5) */
1030
+ topK?: number;
1031
+ /** Minimum similarity for retrieved docs (default: 0.5) */
1032
+ similarityThreshold?: number;
1033
+ /** Custom aggregator URL to use instead of the default */
1034
+ aggregatorUrl?: string;
1035
+ /** Use guest mode for unauthenticated access to policy-free endpoints */
1036
+ guestMode?: boolean;
1037
+ /** AbortSignal for request cancellation */
1038
+ signal?: AbortSignal;
1039
+ }
1040
+ /**
1041
+ * Response from a retrieval-only search via the Aggregator.
1042
+ *
1043
+ * Mirrors {@link ChatResponse} minus the generated text: retrieval runs across
1044
+ * the data sources (with satellite-token auth and MPP payment handled by the
1045
+ * aggregator), but no model is invoked.
1046
+ */
1047
+ interface SearchResponse {
1048
+ /** Retrieved documents across all data sources */
1049
+ documents: SearchDocument[];
1050
+ /** Metadata about each data source retrieval (status, count, errors) */
1051
+ retrievalInfo: SourceInfo[];
1052
+ /** Timing metadata */
1053
+ metadata: ChatMetadata;
1054
+ /** Aggregated payment-policy metadata across queried sources */
1055
+ billing?: Billing;
1056
+ }
1057
+ /**
1058
+ * Result of a direct data-source query (`client.syftai.queryDataSource`).
1059
+ *
1060
+ * Carries the retrieved documents plus the raw `policyMetadata` block from the
1061
+ * syft-space `/query` response (Boundary A), so direct-query callers get the
1062
+ * same authoritative payment/policy metadata the aggregator surfaces.
1063
+ */
1064
+ interface DataSourceQueryResult {
1065
+ /** Retrieved documents */
1066
+ documents: Document[];
1067
+ /** Raw policy metadata from the syft-space response, if present */
1068
+ policyMetadata?: PolicyMetadata;
1069
+ }
898
1070
  /**
899
1071
  * Options for querying a data source directly.
900
1072
  */
@@ -1019,6 +1191,8 @@ interface DoneEvent {
1019
1191
  usage?: TokenUsage;
1020
1192
  /** Normalized contribution scores per source (owner/slug to fraction 0-1) */
1021
1193
  profitShare?: Record<string, number>;
1194
+ /** Aggregated payment-policy metadata across queried sources */
1195
+ billing?: Billing;
1022
1196
  /**
1023
1197
  * Clean response text with attribution markers stripped.
1024
1198
  * Present when attribution ran (data sources were used). Frontends should
@@ -1032,6 +1206,11 @@ interface DoneEvent {
1032
1206
  interface ErrorEvent {
1033
1207
  type: 'error';
1034
1208
  message: string;
1209
+ /**
1210
+ * Billing surfaced on the error path: a paid query may be REJECTED yet still
1211
+ * carry policy/billing metadata (e.g. a charge that must be refunded).
1212
+ */
1213
+ billing?: Billing;
1035
1214
  }
1036
1215
  /**
1037
1216
  * Discriminated union of all streaming event types.
@@ -1055,6 +1234,131 @@ interface ErrorEvent {
1055
1234
  */
1056
1235
  type ChatStreamEvent = RetrievalStartEvent | SourceCompleteEvent | RetrievalCompleteEvent | RerankingStartEvent | RerankingCompleteEvent | GenerationStartEvent | GenerationHeartbeatEvent | TokenEvent$1 | DoneEvent | ErrorEvent;
1057
1236
 
1237
+ /**
1238
+ * Resource for managing user's aggregator configurations.
1239
+ *
1240
+ * Aggregators are custom RAG orchestration service endpoints that users can
1241
+ * configure to use for chat operations. Each user can have multiple aggregator
1242
+ * configurations, with one set as the default.
1243
+ *
1244
+ * The first aggregator created is automatically set as the default. Only one
1245
+ * aggregator can be the default at a time; setting a new default automatically
1246
+ * unsets the previous one.
1247
+ *
1248
+ * @example
1249
+ * // List all aggregators
1250
+ * const aggregators = await client.users.aggregators.list();
1251
+ * for (const agg of aggregators) {
1252
+ * console.log(`${agg.name}: ${agg.url}`);
1253
+ * }
1254
+ *
1255
+ * @example
1256
+ * // Create a new aggregator
1257
+ * const agg = await client.users.aggregators.create({
1258
+ * name: 'My Custom Aggregator',
1259
+ * url: 'https://my-aggregator.example.com'
1260
+ * });
1261
+ *
1262
+ * @example
1263
+ * // Set as default
1264
+ * const defaultAgg = await client.users.aggregators.setDefault(agg.id);
1265
+ */
1266
+ declare class AggregatorsResource {
1267
+ private readonly http;
1268
+ constructor(http: HTTPClient);
1269
+ /**
1270
+ * List all aggregator configurations for the current user.
1271
+ *
1272
+ * @returns Array of UserAggregator objects
1273
+ * @throws {AuthenticationError} If not authenticated
1274
+ *
1275
+ * @example
1276
+ * const aggregators = await client.users.aggregators.list();
1277
+ * for (const agg of aggregators) {
1278
+ * if (agg.isDefault) {
1279
+ * console.log(`Default: ${agg.name}`);
1280
+ * }
1281
+ * }
1282
+ */
1283
+ list(): Promise<UserAggregator[]>;
1284
+ /**
1285
+ * Get a specific aggregator configuration by ID.
1286
+ *
1287
+ * @param aggregatorId - The aggregator ID
1288
+ * @returns The UserAggregator object
1289
+ * @throws {AuthenticationError} If not authenticated
1290
+ * @throws {NotFoundError} If aggregator not found
1291
+ *
1292
+ * @example
1293
+ * const agg = await client.users.aggregators.get(1);
1294
+ * console.log(`${agg.name}: ${agg.url}`);
1295
+ */
1296
+ get(aggregatorId: number): Promise<UserAggregator>;
1297
+ /**
1298
+ * Create a new aggregator configuration.
1299
+ *
1300
+ * The first aggregator created is automatically set as the default.
1301
+ *
1302
+ * @param input - Aggregator creation input
1303
+ * @returns The created UserAggregator object
1304
+ * @throws {AuthenticationError} If not authenticated
1305
+ * @throws {ValidationError} If input is invalid
1306
+ *
1307
+ * @example
1308
+ * const agg = await client.users.aggregators.create({
1309
+ * name: 'My Custom Aggregator',
1310
+ * url: 'https://my-aggregator.example.com'
1311
+ * });
1312
+ * console.log(`Created: ${agg.id}`);
1313
+ */
1314
+ create(input: UserAggregatorCreateInput): Promise<UserAggregator>;
1315
+ /**
1316
+ * Update an aggregator configuration.
1317
+ *
1318
+ * Only provided fields will be updated.
1319
+ *
1320
+ * @param aggregatorId - The aggregator ID to update
1321
+ * @param input - Fields to update
1322
+ * @returns The updated UserAggregator object
1323
+ * @throws {AuthenticationError} If not authenticated
1324
+ * @throws {NotFoundError} If aggregator not found
1325
+ * @throws {ValidationError} If input is invalid
1326
+ *
1327
+ * @example
1328
+ * const agg = await client.users.aggregators.update(1, {
1329
+ * name: 'Updated Name'
1330
+ * });
1331
+ */
1332
+ update(aggregatorId: number, input: UserAggregatorUpdateInput): Promise<UserAggregator>;
1333
+ /**
1334
+ * Delete an aggregator configuration.
1335
+ *
1336
+ * @param aggregatorId - The aggregator ID to delete
1337
+ * @throws {AuthenticationError} If not authenticated
1338
+ * @throws {NotFoundError} If aggregator not found
1339
+ *
1340
+ * @example
1341
+ * await client.users.aggregators.delete(1);
1342
+ */
1343
+ delete(aggregatorId: number): Promise<void>;
1344
+ /**
1345
+ * Set an aggregator as the default.
1346
+ *
1347
+ * Only one aggregator can be the default at a time. Setting a new default
1348
+ * automatically unsets the previous one.
1349
+ *
1350
+ * @param aggregatorId - The aggregator ID to set as default
1351
+ * @returns The updated UserAggregator object with isDefault=true
1352
+ * @throws {AuthenticationError} If not authenticated
1353
+ * @throws {NotFoundError} If aggregator not found
1354
+ *
1355
+ * @example
1356
+ * const agg = await client.users.aggregators.setDefault(2);
1357
+ * console.log(`${agg.name} is now the default`);
1358
+ */
1359
+ setDefault(aggregatorId: number): Promise<UserAggregator>;
1360
+ }
1361
+
1058
1362
  /**
1059
1363
  * Authentication resource for login, register, and session management.
1060
1364
  *
@@ -1361,131 +1665,6 @@ interface SatelliteTokenResponse {
1361
1665
  expiresIn: number;
1362
1666
  }
1363
1667
 
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>;
1471
- /**
1472
- * Set an aggregator as the default.
1473
- *
1474
- * Only one aggregator can be the default at a time. Setting a new default
1475
- * automatically unsets the previous one.
1476
- *
1477
- * @param aggregatorId - The aggregator ID to set as default
1478
- * @returns The updated UserAggregator object with isDefault=true
1479
- * @throws {AuthenticationError} If not authenticated
1480
- * @throws {NotFoundError} If aggregator not found
1481
- *
1482
- * @example
1483
- * const agg = await client.users.aggregators.setDefault(2);
1484
- * console.log(`${agg.name} is now the default`);
1485
- */
1486
- setDefault(aggregatorId: number): Promise<UserAggregator>;
1487
- }
1488
-
1489
1668
  /**
1490
1669
  * Users resource for profile management and availability checks.
1491
1670
  *
@@ -2581,7 +2760,19 @@ declare class AgentSessionClient {
2581
2760
  declare class AggregatorError extends SyftHubError {
2582
2761
  readonly status?: number | undefined;
2583
2762
  readonly detail?: unknown | undefined;
2584
- constructor(message: string, status?: number | undefined, detail?: unknown | undefined);
2763
+ /**
2764
+ * Billing/policy metadata the aggregator may attach even on an error
2765
+ * response — a paid query can be REJECTED yet still carry a charge that
2766
+ * must be surfaced (and possibly refunded).
2767
+ */
2768
+ readonly billing?: Billing | undefined;
2769
+ constructor(message: string, status?: number | undefined, detail?: unknown | undefined,
2770
+ /**
2771
+ * Billing/policy metadata the aggregator may attach even on an error
2772
+ * response — a paid query can be REJECTED yet still carry a charge that
2773
+ * must be surfaced (and possibly refunded).
2774
+ */
2775
+ billing?: Billing | undefined);
2585
2776
  }
2586
2777
  /**
2587
2778
  * Error thrown when an endpoint cannot be resolved.
@@ -2690,6 +2881,20 @@ declare class ChatResource {
2690
2881
  * Parse TokenUsage from raw data.
2691
2882
  */
2692
2883
  private parseUsage;
2884
+ /**
2885
+ * Parse a single billing/policy-metadata entry from a raw (snake_case) dict.
2886
+ *
2887
+ * Shared by {@link parseBilling} (aggregated, carries `source`) and the
2888
+ * direct-path `policy_metadata` parsing in {@link SyftAIResource}.
2889
+ */
2890
+ static parseBillingEntry(raw: Record<string, unknown>): BillingEntry;
2891
+ /**
2892
+ * Parse the aggregated `billing` block from a raw aggregator response.
2893
+ *
2894
+ * Returns undefined when no `billing` object is present (e.g. an error body
2895
+ * with no policy metadata). The wire keys are snake_case.
2896
+ */
2897
+ private parseBilling;
2693
2898
  /**
2694
2899
  * Parse document sources from raw data.
2695
2900
  * The new format is a dict mapping document title to {slug, content}.
@@ -2714,6 +2919,28 @@ declare class ChatResource {
2714
2919
  * @throws {AggregatorError} If aggregator service fails
2715
2920
  */
2716
2921
  complete(options: ChatOptions): Promise<ChatResponse>;
2922
+ /**
2923
+ * Placeholder model for retrieval-only requests. The aggregator requires a
2924
+ * `model` field on every request, but short-circuits before dereferencing it
2925
+ * when `retrieval_only` is set, so an empty ref is never contacted.
2926
+ */
2927
+ private static readonly RETRIEVAL_ONLY_MODEL;
2928
+ /**
2929
+ * Retrieve documents from data sources without model generation.
2930
+ *
2931
+ * Drives the aggregator's retrieval-only path: data sources are queried in
2932
+ * parallel (with satellite-token auth and MPP payment handled server-side,
2933
+ * exactly like {@link complete}), but no model is invoked.
2934
+ *
2935
+ * Prefer the symmetric `client.search.query(...)` facade; this is the
2936
+ * underlying primitive.
2937
+ *
2938
+ * @param options - Search options
2939
+ * @returns SearchResponse with retrieved documents and per-source metadata
2940
+ * @throws {EndpointResolutionError} If a data source cannot be resolved
2941
+ * @throws {AggregatorError} If the aggregator service fails
2942
+ */
2943
+ retrieve(options: SearchQueryOptions): Promise<SearchResponse>;
2717
2944
  /**
2718
2945
  * Send a chat request and stream response events.
2719
2946
  *
@@ -2748,6 +2975,58 @@ declare class ChatResource {
2748
2975
  getAvailableDataSources(limit?: number): Promise<EndpointPublic[]>;
2749
2976
  }
2750
2977
 
2978
+ /**
2979
+ * Search resource for retrieval-only queries via the Aggregator service.
2980
+ *
2981
+ * Symmetric counterpart to {@link ChatResource}: where `client.chat.complete()`
2982
+ * retrieves context *and* generates a model response, `client.search.query()`
2983
+ * retrieves documents from data sources without invoking any model.
2984
+ *
2985
+ * @example
2986
+ * // Symmetric to client.chat.complete(...)
2987
+ * const result = await client.search.query({
2988
+ * prompt: 'What happened at EPFL this week?',
2989
+ * dataSources: ['epfl-news/epfl-news'],
2990
+ * });
2991
+ * for (const doc of result.documents) {
2992
+ * console.log(doc.title, '->', doc.content.slice(0, 80));
2993
+ * }
2994
+ *
2995
+ * Authentication and billing are handled by the aggregator exactly as for chat:
2996
+ * satellite tokens are minted per data source owner, and metered endpoints that
2997
+ * respond with `402 Payment Required` are settled via the user's Hub wallet.
2998
+ */
2999
+
3000
+ /**
3001
+ * Retrieval-only search via the Aggregator.
3002
+ *
3003
+ * Thin facade over {@link ChatResource.retrieve}, exposed as `client.search` to
3004
+ * mirror the shape of `client.chat`.
3005
+ */
3006
+ declare class SearchResource {
3007
+ private readonly chat;
3008
+ /**
3009
+ * @param chat - The chat resource that owns aggregator communication and
3010
+ * request preparation (satellite tokens, MPP, collective expansion). Search
3011
+ * reuses it rather than duplicating that logic.
3012
+ */
3013
+ constructor(chat: ChatResource);
3014
+ /**
3015
+ * Retrieve documents from data sources without model generation.
3016
+ *
3017
+ * @param options - Search options (prompt, data sources, top-k, etc.)
3018
+ * @returns SearchResponse with retrieved documents and per-source metadata
3019
+ *
3020
+ * @example
3021
+ * const result = await client.search.query({
3022
+ * prompt: 'Hello, world!',
3023
+ * dataSources: ['epfl-news/epfl-news'],
3024
+ * });
3025
+ * console.log(result.documents.length, 'documents');
3026
+ */
3027
+ query(options: SearchQueryOptions): Promise<SearchResponse>;
3028
+ }
3029
+
2751
3030
  /**
2752
3031
  * SyftAI-Space resource for direct endpoint queries.
2753
3032
  *
@@ -2837,6 +3116,15 @@ declare class SyftAIResource {
2837
3116
  * `score`) is still honoured for backward compatibility.
2838
3117
  */
2839
3118
  private parseDocuments;
3119
+ /**
3120
+ * Parse the raw `policy_metadata` block from a syft-space response.
3121
+ *
3122
+ * The direct path (Boundary A) carries a top-level `policy_metadata` object
3123
+ * shaped `{ outcome, entries: [...] }`. Entries reuse the {@link BillingEntry}
3124
+ * shape (with `source` absent), so this delegates entry parsing to
3125
+ * {@link ChatResource.parseBillingEntry}. The wire keys are snake_case.
3126
+ */
3127
+ private parsePolicyMetadata;
2840
3128
  /**
2841
3129
  * Query a data source endpoint directly.
2842
3130
  *
@@ -2846,10 +3134,12 @@ declare class SyftAIResource {
2846
3134
  * owner is known (`ownerUsername` option or `endpoint.ownerUsername`).
2847
3135
  *
2848
3136
  * @param options - Query options
2849
- * @returns Array of Document objects
3137
+ * @returns DataSourceQueryResult the retrieved documents plus the raw
3138
+ * `policyMetadata` block from the syft-space response (price, recipient,
3139
+ * transaction, status).
2850
3140
  * @throws {RetrievalError} If the query fails
2851
3141
  */
2852
- queryDataSource(options: QueryDataSourceOptions): Promise<Document[]>;
3142
+ queryDataSource(options: QueryDataSourceOptions): Promise<DataSourceQueryResult>;
2853
3143
  /**
2854
3144
  * Query a model endpoint directly.
2855
3145
  *
@@ -2948,8 +3238,10 @@ declare class SyftHubClient {
2948
3238
  private _myEndpoints?;
2949
3239
  private _hub?;
2950
3240
  private _accounting?;
3241
+ private _aggregators?;
2951
3242
  private _agent?;
2952
3243
  private _chat?;
3244
+ private _search?;
2953
3245
  private _syftai?;
2954
3246
  private _apiTokens?;
2955
3247
  /**
@@ -3029,22 +3321,8 @@ declare class SyftHubClient {
3029
3321
  */
3030
3322
  get accounting(): AccountingResource;
3031
3323
  /**
3032
- * Initialize the accounting (wallet) resource.
3033
- *
3034
- * The wallet API uses the same SyftHub authentication as other resources.
3035
- * This method simply verifies authentication and creates the resource.
3036
- *
3037
- * @returns The initialized AccountingResource
3038
- * @throws {AuthenticationError} If not authenticated
3039
- *
3040
- * @example
3041
- * // Login first, then initialize accounting
3042
- * await client.auth.login('alice', 'password');
3043
- * await client.initAccounting();
3044
- *
3045
- * // Now accounting is available
3046
- * const wallet = await client.accounting.getWallet();
3047
- * const balance = await client.accounting.getBalance();
3324
+ * @deprecated Accounting is now initialized automatically on first access.
3325
+ * This method is kept for backward compatibility and is a no-op.
3048
3326
  */
3049
3327
  initAccounting(): Promise<AccountingResource>;
3050
3328
  /**
@@ -3074,6 +3352,23 @@ declare class SyftHubClient {
3074
3352
  * const sources = await client.chat.getAvailableDataSources();
3075
3353
  */
3076
3354
  get chat(): ChatResource;
3355
+ /**
3356
+ * Retrieval-only search via the Aggregator (no model generation).
3357
+ *
3358
+ * Symmetric counterpart to {@link chat}: queries data sources for relevant
3359
+ * documents without invoking a model. Satellite-token auth and MPP payment
3360
+ * are handled by the aggregator exactly as for chat.
3361
+ *
3362
+ * @example
3363
+ * const result = await client.search.query({
3364
+ * prompt: 'Hello, world!',
3365
+ * dataSources: ['epfl-news/epfl-news'],
3366
+ * });
3367
+ * for (const doc of result.documents) {
3368
+ * console.log(doc.title, doc.content.slice(0, 80));
3369
+ * }
3370
+ */
3371
+ get search(): SearchResource;
3077
3372
  /**
3078
3373
  * SyftAI-Space resource for direct endpoint queries (low-level API).
3079
3374
  *
@@ -3119,6 +3414,7 @@ declare class SyftHubClient {
3119
3414
  * // Revoke a token
3120
3415
  * await client.apiTokens.revoke(tokenId);
3121
3416
  */
3417
+ get aggregators(): AggregatorsResource;
3122
3418
  get apiTokens(): APITokensResource;
3123
3419
  /**
3124
3420
  * Check if the client is using API token authentication.
@@ -3182,4 +3478,4 @@ declare class SyftHubClient {
3182
3478
  close(): void;
3183
3479
  }
3184
3480
 
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 };
3481
+ 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 Billing, type BillingEntry, type BrowseOptions, type ChatMetadata, type ChatOptions, ChatResource, type ChatResponse, type ChatStreamEvent, ConfigurationError, type Connection, type CreateAPITokenInput, type DataSourceQueryResult, 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 PolicyMetadata, type QueryDataSourceOptions, type QueryModelOptions, type ReasonCode, type Recipient, type RegisterResult, type RetrievalCompleteEvent, RetrievalError, type RetrievalStartEvent, type SearchDocument, type SearchQueryOptions, SearchResource, type SearchResponse, type SourceCompleteEvent, type SourceInfo, type SourceStatus, SyftAIResource, SyftHubClient, type SyftHubClientOptions, SyftHubError, type SyncEndpointsResponse, type TokenEvent$1 as TokenEvent, type Transaction, 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 };