@vectros-ai/mcp-server 0.18.1 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -3,7 +3,7 @@
3
3
  // src/server.ts
4
4
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
5
5
 
6
- // ../../node_modules/@vectros-ai/sdk/dist/index.mjs
6
+ // node_modules/@vectros-ai/sdk/dist/index.mjs
7
7
  var __defProp = Object.defineProperty;
8
8
  var __export = (target, all) => {
9
9
  for (var name in all)
@@ -18,10 +18,13 @@ __export(api_exports, {
18
18
  BatchWriteRequest: () => BatchWriteRequest,
19
19
  BatchWriteResult: () => BatchWriteResult,
20
20
  ChatMessage: () => ChatMessage,
21
+ ChatRequest: () => ChatRequest,
21
22
  ConflictError: () => ConflictError,
22
23
  ContentDeltaEvent: () => ContentDeltaEvent,
23
24
  ContentTooLargeError: () => ContentTooLargeError,
25
+ DocumentAskRequest: () => DocumentAskRequest,
24
26
  DocumentContextEvent: () => DocumentContextEvent,
27
+ DocumentExtraction: () => DocumentExtraction,
25
28
  DocumentLookupRequest: () => DocumentLookupRequest,
26
29
  DocumentPatchRequest: () => DocumentPatchRequest,
27
30
  DocumentRequest: () => DocumentRequest,
@@ -51,8 +54,10 @@ __export(api_exports, {
51
54
  NotImplementedError: () => NotImplementedError,
52
55
  PaymentRequiredError: () => PaymentRequiredError,
53
56
  PingResponse: () => PingResponse,
57
+ RagRequest: () => RagRequest,
54
58
  RagSearch: () => RagSearch,
55
59
  ReadAccessLogResponse: () => ReadAccessLogResponse,
60
+ ReasoningDeltaEvent: () => ReasoningDeltaEvent,
56
61
  RecordLookupRequest: () => RecordLookupRequest,
57
62
  RecordRequest: () => RecordRequest,
58
63
  RecordResponse: () => RecordResponse,
@@ -72,6 +77,7 @@ __export(api_exports, {
72
77
  UserExistsResponse: () => UserExistsResponse,
73
78
  UserRequest: () => UserRequest,
74
79
  UserResponse: () => UserResponse,
80
+ agents: () => agents_exports,
75
81
  auth: () => auth_exports,
76
82
  compliance: () => compliance_exports,
77
83
  documents: () => documents_exports,
@@ -337,6 +343,7 @@ var UnprocessableEntityError = class extends VectrosError {
337
343
  this.name = this.constructor.name;
338
344
  }
339
345
  };
346
+ var agents_exports = {};
340
347
  var auth_exports = {};
341
348
  var ErasureRequest;
342
349
  ((ErasureRequest2) => {
@@ -408,7 +415,33 @@ var ListUsersRequestOrder = {
408
415
  Asc: "asc",
409
416
  Desc: "desc"
410
417
  };
418
+ var ChatRequest;
419
+ ((ChatRequest2) => {
420
+ ChatRequest2.Reasoning = {
421
+ Omit: "omit",
422
+ Stream: "stream"
423
+ };
424
+ })(ChatRequest || (ChatRequest = {}));
425
+ var DocumentAskRequest;
426
+ ((DocumentAskRequest2) => {
427
+ DocumentAskRequest2.Reasoning = {
428
+ Omit: "omit",
429
+ Stream: "stream"
430
+ };
431
+ })(DocumentAskRequest || (DocumentAskRequest = {}));
432
+ var RagRequest;
433
+ ((RagRequest2) => {
434
+ RagRequest2.Reasoning = {
435
+ Omit: "omit",
436
+ Stream: "stream"
437
+ };
438
+ })(RagRequest || (RagRequest = {}));
411
439
  var inference_exports = {};
440
+ __export(inference_exports, {
441
+ ChatRequest: () => ChatRequest,
442
+ DocumentAskRequest: () => DocumentAskRequest,
443
+ RagRequest: () => RagRequest
444
+ });
412
445
  var BatchWriteRequest;
413
446
  ((BatchWriteRequest2) => {
414
447
  BatchWriteRequest2.Atomicity = {
@@ -515,6 +548,18 @@ var DocumentContextEvent;
515
548
  DocumentContext: "document_context"
516
549
  };
517
550
  })(DocumentContextEvent || (DocumentContextEvent = {}));
551
+ var DocumentExtraction;
552
+ ((DocumentExtraction2) => {
553
+ DocumentExtraction2.Outcome = {
554
+ Ok: "OK",
555
+ Truncated: "TRUNCATED",
556
+ NoText: "NO_TEXT",
557
+ Encrypted: "ENCRYPTED",
558
+ Unsupported: "UNSUPPORTED",
559
+ TooLarge: "TOO_LARGE",
560
+ Unreadable: "UNREADABLE"
561
+ };
562
+ })(DocumentExtraction || (DocumentExtraction = {}));
518
563
  var DocumentRequest;
519
564
  ((DocumentRequest2) => {
520
565
  DocumentRequest2.IndexMode = {
@@ -681,6 +726,12 @@ var ReadAccessLogResponse;
681
726
  Rag: "rag"
682
727
  };
683
728
  })(ReadAccessLogResponse || (ReadAccessLogResponse = {}));
729
+ var ReasoningDeltaEvent;
730
+ ((ReasoningDeltaEvent2) => {
731
+ ReasoningDeltaEvent2.Event = {
732
+ ReasoningDelta: "reasoning_delta"
733
+ };
734
+ })(ReasoningDeltaEvent || (ReasoningDeltaEvent = {}));
684
735
  var RecordRequest;
685
736
  ((RecordRequest2) => {
686
737
  RecordRequest2.Status = {
@@ -1814,13 +1865,13 @@ function joinPathSegments(left, right) {
1814
1865
  }
1815
1866
  return `${left}/${right}`;
1816
1867
  }
1817
- function trimSlashes(str) {
1818
- if (!str) return str;
1868
+ function trimSlashes(str2) {
1869
+ if (!str2) return str2;
1819
1870
  let start = 0;
1820
- let end = str.length;
1821
- if (str.startsWith("/")) start = 1;
1822
- if (str.endsWith("/")) end = str.length - 1;
1823
- return start === 0 && end === str.length ? str : str.slice(start, end);
1871
+ let end = str2.length;
1872
+ if (str2.startsWith("/")) start = 1;
1873
+ if (str2.endsWith("/")) end = str2.length - 1;
1874
+ return start === 0 && end === str2.length ? str2 : str2.slice(start, end);
1824
1875
  }
1825
1876
  var Supplier = {
1826
1877
  get: async (supplier) => {
@@ -2243,140 +2294,767 @@ var QueryStringBuilder = class {
2243
2294
  }
2244
2295
  }
2245
2296
  }
2246
- return this;
2297
+ return this;
2298
+ }
2299
+ /**
2300
+ * Returns the assembled query string (without the leading `?`).
2301
+ * Returns an empty string when no parameters were added.
2302
+ */
2303
+ build() {
2304
+ return [...this.parts.values()].join("&");
2305
+ }
2306
+ };
2307
+ var TOKEN_PARAM = "token";
2308
+ var BearerAuthProvider = class _BearerAuthProvider {
2309
+ constructor(options) {
2310
+ this.options = options;
2311
+ }
2312
+ static canCreate(options) {
2313
+ return options?.[TOKEN_PARAM] != null;
2314
+ }
2315
+ async getAuthRequest({
2316
+ endpointMetadata
2317
+ } = {}) {
2318
+ const token = await Supplier.get(this.options[TOKEN_PARAM]);
2319
+ if (token == null) {
2320
+ throw new VectrosError({
2321
+ message: _BearerAuthProvider.AUTH_CONFIG_ERROR_MESSAGE
2322
+ });
2323
+ }
2324
+ return {
2325
+ headers: { Authorization: `Bearer ${token}` }
2326
+ };
2327
+ }
2328
+ };
2329
+ ((BearerAuthProvider2) => {
2330
+ BearerAuthProvider2.AUTH_SCHEME = "BearerAuth";
2331
+ BearerAuthProvider2.AUTH_CONFIG_ERROR_MESSAGE = `Please provide '${TOKEN_PARAM}' when initializing the client`;
2332
+ function createInstance(options) {
2333
+ return new BearerAuthProvider2(options);
2334
+ }
2335
+ BearerAuthProvider2.createInstance = createInstance;
2336
+ })(BearerAuthProvider || (BearerAuthProvider = {}));
2337
+ function mergeHeaders(...headersArray) {
2338
+ const result = {};
2339
+ for (const [key, value] of headersArray.filter((headers) => headers != null).flatMap((headers) => Object.entries(headers))) {
2340
+ const insensitiveKey = key.toLowerCase();
2341
+ if (value != null) {
2342
+ result[insensitiveKey] = value;
2343
+ } else if (insensitiveKey in result) {
2344
+ delete result[insensitiveKey];
2345
+ }
2346
+ }
2347
+ return result;
2348
+ }
2349
+ function mergeOnlyDefinedHeaders(...headersArray) {
2350
+ const result = {};
2351
+ for (const [key, value] of headersArray.filter((headers) => headers != null).flatMap((headers) => Object.entries(headers))) {
2352
+ const insensitiveKey = key.toLowerCase();
2353
+ if (value != null) {
2354
+ result[insensitiveKey] = value;
2355
+ }
2356
+ }
2357
+ return result;
2358
+ }
2359
+ function normalizeClientOptions(options) {
2360
+ const headers = mergeHeaders(
2361
+ {
2362
+ "X-Fern-Language": "JavaScript",
2363
+ "X-Fern-Runtime": RUNTIME.type,
2364
+ "X-Fern-Runtime-Version": RUNTIME.version
2365
+ },
2366
+ options?.headers
2367
+ );
2368
+ return {
2369
+ ...options,
2370
+ logging: logging_exports.createLogger(options?.logging),
2371
+ headers
2372
+ };
2373
+ }
2374
+ function normalizeClientOptionsWithAuth(options) {
2375
+ const normalized = normalizeClientOptions(options);
2376
+ if (options.auth === false) {
2377
+ normalized.authProvider = new NoOpAuthProvider();
2378
+ return normalized;
2379
+ }
2380
+ if (options.auth != null) {
2381
+ if (typeof options.auth === "function") {
2382
+ normalized.authProvider = { getAuthRequest: options.auth };
2383
+ return normalized;
2384
+ }
2385
+ if (isAuthProvider(options.auth)) {
2386
+ normalized.authProvider = options.auth;
2387
+ return normalized;
2388
+ }
2389
+ Object.assign(normalized, options.auth);
2390
+ }
2391
+ const normalizedWithNoOpAuthProvider = withNoOpAuthProvider(normalized);
2392
+ normalized.authProvider ?? (normalized.authProvider = new BearerAuthProvider(normalizedWithNoOpAuthProvider));
2393
+ return normalized;
2394
+ }
2395
+ function withNoOpAuthProvider(options) {
2396
+ return {
2397
+ ...options,
2398
+ authProvider: new NoOpAuthProvider()
2399
+ };
2400
+ }
2401
+ function handleNonStatusCodeError(error, rawResponse, method, path2) {
2402
+ switch (error.reason) {
2403
+ case "non-json":
2404
+ throw new VectrosError({
2405
+ statusCode: error.statusCode,
2406
+ body: error.rawBody,
2407
+ rawResponse
2408
+ });
2409
+ case "body-is-null":
2410
+ throw new VectrosError({
2411
+ statusCode: error.statusCode,
2412
+ rawResponse
2413
+ });
2414
+ case "timeout":
2415
+ throw new VectrosTimeoutError(`Timeout exceeded when calling ${method} ${path2}.`, {
2416
+ cause: error.cause
2417
+ });
2418
+ case "unknown":
2419
+ throw new VectrosError({
2420
+ message: error.errorMessage,
2421
+ rawResponse,
2422
+ cause: error.cause
2423
+ });
2424
+ default:
2425
+ throw new VectrosError({
2426
+ message: "Unknown error",
2427
+ rawResponse
2428
+ });
2429
+ }
2430
+ }
2431
+ var AgentsClient = class {
2432
+ constructor(options) {
2433
+ this._options = normalizeClientOptionsWithAuth(options);
2434
+ }
2435
+ /**
2436
+ * Returns a page of the agents in the app context, newest first, each at its latest version. A caller holding `runs:c` but not `agents:r` gets only each agent's `id`, `name`, `description`, `latestVersion` and `status`. Retired and purged agents are left out unless `includeRetired=true`. Requires `agents:r` or `runs:c`.
2437
+ *
2438
+ * @param {Vectros.ListAgentsRequest} request
2439
+ * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration.
2440
+ *
2441
+ * @throws {@link Vectros.ForbiddenError}
2442
+ *
2443
+ * @example
2444
+ * await client.agents.listAgents()
2445
+ */
2446
+ listAgents(request = {}, requestOptions) {
2447
+ return HttpResponsePromise.fromPromise(this.__listAgents(request, requestOptions));
2448
+ }
2449
+ async __listAgents(request = {}, requestOptions) {
2450
+ const { contextId, includeRetired, startFrom, limit } = request;
2451
+ const _queryParams = {
2452
+ contextId,
2453
+ includeRetired,
2454
+ startFrom,
2455
+ limit
2456
+ };
2457
+ const _authRequest = await this._options.authProvider.getAuthRequest();
2458
+ const _headers = mergeHeaders(
2459
+ _authRequest.headers,
2460
+ this._options?.headers,
2461
+ requestOptions?.headers
2462
+ );
2463
+ const _response = await fetcher({
2464
+ url: url_exports.join(
2465
+ await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
2466
+ "v1/agents"
2467
+ ),
2468
+ method: "GET",
2469
+ headers: _headers,
2470
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
2471
+ timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
2472
+ maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
2473
+ abortSignal: requestOptions?.abortSignal,
2474
+ fetchFn: this._options?.fetch,
2475
+ logging: this._options.logging
2476
+ });
2477
+ if (_response.ok) {
2478
+ return { data: _response.body, rawResponse: _response.rawResponse };
2479
+ }
2480
+ if (_response.error.reason === "status-code") {
2481
+ switch (_response.error.statusCode) {
2482
+ case 403:
2483
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
2484
+ default:
2485
+ throw new VectrosError({
2486
+ statusCode: _response.error.statusCode,
2487
+ body: _response.error.body,
2488
+ rawResponse: _response.rawResponse
2489
+ });
2490
+ }
2491
+ }
2492
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/agents");
2493
+ }
2494
+ /**
2495
+ * Stores a new agent at version 1, or returns the existing agent of this name unchanged. With `?upsert=true` an existing agent whose definition differs gets a new version instead. Requires the `agents:c` scope (also `agents:u` with `?upsert=true`).
2496
+ *
2497
+ * @param {Vectros.CreateAgentRequest} request
2498
+ * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration.
2499
+ *
2500
+ * @throws {@link Vectros.BadRequestError}
2501
+ * @throws {@link Vectros.ForbiddenError}
2502
+ * @throws {@link Vectros.ConflictError}
2503
+ * @throws {@link Vectros.TooManyRequestsError}
2504
+ *
2505
+ * @example
2506
+ * await client.agents.createAgent({
2507
+ * body: {
2508
+ * model: "claude-sonnet-5-5"
2509
+ * }
2510
+ * })
2511
+ */
2512
+ createAgent(request, requestOptions) {
2513
+ return HttpResponsePromise.fromPromise(this.__createAgent(request, requestOptions));
2514
+ }
2515
+ async __createAgent(request, requestOptions) {
2516
+ const { upsert, contextId, body: _body } = request;
2517
+ const _queryParams = {
2518
+ upsert,
2519
+ contextId
2520
+ };
2521
+ const _authRequest = await this._options.authProvider.getAuthRequest();
2522
+ const _headers = mergeHeaders(
2523
+ _authRequest.headers,
2524
+ this._options?.headers,
2525
+ requestOptions?.headers
2526
+ );
2527
+ const _response = await fetcher({
2528
+ url: url_exports.join(
2529
+ await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
2530
+ "v1/agents"
2531
+ ),
2532
+ method: "POST",
2533
+ headers: _headers,
2534
+ contentType: "application/json",
2535
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
2536
+ requestType: "json",
2537
+ body: _body,
2538
+ timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
2539
+ maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
2540
+ abortSignal: requestOptions?.abortSignal,
2541
+ fetchFn: this._options?.fetch,
2542
+ logging: this._options.logging
2543
+ });
2544
+ if (_response.ok) {
2545
+ return { data: _response.body, rawResponse: _response.rawResponse };
2546
+ }
2547
+ if (_response.error.reason === "status-code") {
2548
+ switch (_response.error.statusCode) {
2549
+ case 400:
2550
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
2551
+ case 403:
2552
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
2553
+ case 409:
2554
+ throw new ConflictError(_response.error.body, _response.rawResponse);
2555
+ case 429:
2556
+ throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
2557
+ default:
2558
+ throw new VectrosError({
2559
+ statusCode: _response.error.statusCode,
2560
+ body: _response.error.body,
2561
+ rawResponse: _response.rawResponse
2562
+ });
2563
+ }
2564
+ }
2565
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/agents");
2566
+ }
2567
+ /**
2568
+ * Returns the agent at its latest version, or at `version`. Requires the `agents:r` scope.
2569
+ *
2570
+ * @param {Vectros.GetAgentRequest} request
2571
+ * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration.
2572
+ *
2573
+ * @throws {@link Vectros.ForbiddenError}
2574
+ * @throws {@link Vectros.NotFoundError}
2575
+ *
2576
+ * @example
2577
+ * await client.agents.getAgent({
2578
+ * id: "id"
2579
+ * })
2580
+ */
2581
+ getAgent(request, requestOptions) {
2582
+ return HttpResponsePromise.fromPromise(this.__getAgent(request, requestOptions));
2583
+ }
2584
+ async __getAgent(request, requestOptions) {
2585
+ const { id, contextId, version } = request;
2586
+ const _queryParams = {
2587
+ contextId,
2588
+ version
2589
+ };
2590
+ const _authRequest = await this._options.authProvider.getAuthRequest();
2591
+ const _headers = mergeHeaders(
2592
+ _authRequest.headers,
2593
+ this._options?.headers,
2594
+ requestOptions?.headers
2595
+ );
2596
+ const _response = await fetcher({
2597
+ url: url_exports.join(
2598
+ await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
2599
+ `v1/agents/${url_exports.encodePathParam(id)}`
2600
+ ),
2601
+ method: "GET",
2602
+ headers: _headers,
2603
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
2604
+ timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
2605
+ maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
2606
+ abortSignal: requestOptions?.abortSignal,
2607
+ fetchFn: this._options?.fetch,
2608
+ logging: this._options.logging
2609
+ });
2610
+ if (_response.ok) {
2611
+ return { data: _response.body, rawResponse: _response.rawResponse };
2612
+ }
2613
+ if (_response.error.reason === "status-code") {
2614
+ switch (_response.error.statusCode) {
2615
+ case 403:
2616
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
2617
+ case 404:
2618
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
2619
+ default:
2620
+ throw new VectrosError({
2621
+ statusCode: _response.error.statusCode,
2622
+ body: _response.error.body,
2623
+ rawResponse: _response.rawResponse
2624
+ });
2625
+ }
2626
+ }
2627
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/agents/{id}");
2628
+ }
2629
+ /**
2630
+ * Stores the body as the agent's next version. Earlier versions never change. Every optional field you leave out takes its default; `model` is required. With `?restore=true` a retired agent becomes active again with this version. Requires the `agents:u` scope.
2631
+ *
2632
+ * @param {Vectros.UpdateAgentRequest} request
2633
+ * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration.
2634
+ *
2635
+ * @throws {@link Vectros.BadRequestError}
2636
+ * @throws {@link Vectros.ForbiddenError}
2637
+ * @throws {@link Vectros.NotFoundError}
2638
+ * @throws {@link Vectros.ConflictError}
2639
+ * @throws {@link Vectros.TooManyRequestsError}
2640
+ *
2641
+ * @example
2642
+ * await client.agents.updateAgent({
2643
+ * id: "id",
2644
+ * body: {
2645
+ * model: "claude-sonnet-5-5"
2646
+ * }
2647
+ * })
2648
+ */
2649
+ updateAgent(request, requestOptions) {
2650
+ return HttpResponsePromise.fromPromise(this.__updateAgent(request, requestOptions));
2651
+ }
2652
+ async __updateAgent(request, requestOptions) {
2653
+ const { id, restore, contextId, body: _body } = request;
2654
+ const _queryParams = {
2655
+ restore,
2656
+ contextId
2657
+ };
2658
+ const _authRequest = await this._options.authProvider.getAuthRequest();
2659
+ const _headers = mergeHeaders(
2660
+ _authRequest.headers,
2661
+ this._options?.headers,
2662
+ requestOptions?.headers
2663
+ );
2664
+ const _response = await fetcher({
2665
+ url: url_exports.join(
2666
+ await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
2667
+ `v1/agents/${url_exports.encodePathParam(id)}`
2668
+ ),
2669
+ method: "PUT",
2670
+ headers: _headers,
2671
+ contentType: "application/json",
2672
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
2673
+ requestType: "json",
2674
+ body: _body,
2675
+ timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
2676
+ maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
2677
+ abortSignal: requestOptions?.abortSignal,
2678
+ fetchFn: this._options?.fetch,
2679
+ logging: this._options.logging
2680
+ });
2681
+ if (_response.ok) {
2682
+ return { data: _response.body, rawResponse: _response.rawResponse };
2683
+ }
2684
+ if (_response.error.reason === "status-code") {
2685
+ switch (_response.error.statusCode) {
2686
+ case 400:
2687
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
2688
+ case 403:
2689
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
2690
+ case 404:
2691
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
2692
+ case 409:
2693
+ throw new ConflictError(_response.error.body, _response.rawResponse);
2694
+ case 429:
2695
+ throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
2696
+ default:
2697
+ throw new VectrosError({
2698
+ statusCode: _response.error.statusCode,
2699
+ body: _response.error.body,
2700
+ rawResponse: _response.rawResponse
2701
+ });
2702
+ }
2703
+ }
2704
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "PUT", "/v1/agents/{id}");
2705
+ }
2706
+ /**
2707
+ * Retires the agent: its versions stay readable, it leaves the default listing, and it can be restored. With `?purge=true` a retired agent's content (every version's prompt, description, tools, model, limits and budget) is erased, leaving its id, name, version numbers and timestamps; its change history keeps only a one-way hash of the prompt, description and tools. If the agent is restored while a purge is running, the purge stops (409) and versions it already erased stay erased; purge it again after retiring it. With `?purge=true&version=N` one version that is not the latest is erased. The name of a purged agent stays reserved. Requires the `agents:d` scope.
2708
+ *
2709
+ * @param {Vectros.DeleteAgentRequest} request
2710
+ * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration.
2711
+ *
2712
+ * @throws {@link Vectros.BadRequestError}
2713
+ * @throws {@link Vectros.ForbiddenError}
2714
+ * @throws {@link Vectros.NotFoundError}
2715
+ * @throws {@link Vectros.ConflictError}
2716
+ * @throws {@link Vectros.TooManyRequestsError}
2717
+ *
2718
+ * @example
2719
+ * await client.agents.deleteAgent({
2720
+ * id: "id"
2721
+ * })
2722
+ */
2723
+ deleteAgent(request, requestOptions) {
2724
+ return HttpResponsePromise.fromPromise(this.__deleteAgent(request, requestOptions));
2725
+ }
2726
+ async __deleteAgent(request, requestOptions) {
2727
+ const { id, purge, version, contextId } = request;
2728
+ const _queryParams = {
2729
+ purge,
2730
+ version,
2731
+ contextId
2732
+ };
2733
+ const _authRequest = await this._options.authProvider.getAuthRequest();
2734
+ const _headers = mergeHeaders(
2735
+ _authRequest.headers,
2736
+ this._options?.headers,
2737
+ requestOptions?.headers
2738
+ );
2739
+ const _response = await fetcher({
2740
+ url: url_exports.join(
2741
+ await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
2742
+ `v1/agents/${url_exports.encodePathParam(id)}`
2743
+ ),
2744
+ method: "DELETE",
2745
+ headers: _headers,
2746
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
2747
+ timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
2748
+ maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
2749
+ abortSignal: requestOptions?.abortSignal,
2750
+ fetchFn: this._options?.fetch,
2751
+ logging: this._options.logging
2752
+ });
2753
+ if (_response.ok) {
2754
+ return { data: _response.body, rawResponse: _response.rawResponse };
2755
+ }
2756
+ if (_response.error.reason === "status-code") {
2757
+ switch (_response.error.statusCode) {
2758
+ case 400:
2759
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
2760
+ case 403:
2761
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
2762
+ case 404:
2763
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
2764
+ case 409:
2765
+ throw new ConflictError(_response.error.body, _response.rawResponse);
2766
+ case 429:
2767
+ throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
2768
+ default:
2769
+ throw new VectrosError({
2770
+ statusCode: _response.error.statusCode,
2771
+ body: _response.error.body,
2772
+ rawResponse: _response.rawResponse
2773
+ });
2774
+ }
2775
+ }
2776
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "DELETE", "/v1/agents/{id}");
2777
+ }
2778
+ /**
2779
+ * Returns a page of the agent's versions, newest first: who wrote each and when, and whether it was purged. With `includeContent=true` each entry carries its full definition. Requires the `agents:r` scope.
2780
+ *
2781
+ * @param {Vectros.ListAgentVersionsRequest} request
2782
+ * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration.
2783
+ *
2784
+ * @throws {@link Vectros.ForbiddenError}
2785
+ * @throws {@link Vectros.NotFoundError}
2786
+ *
2787
+ * @example
2788
+ * await client.agents.listAgentVersions({
2789
+ * id: "id"
2790
+ * })
2791
+ */
2792
+ listAgentVersions(request, requestOptions) {
2793
+ return HttpResponsePromise.fromPromise(this.__listAgentVersions(request, requestOptions));
2794
+ }
2795
+ async __listAgentVersions(request, requestOptions) {
2796
+ const { id, contextId, includeContent, startFrom, limit } = request;
2797
+ const _queryParams = {
2798
+ contextId,
2799
+ includeContent,
2800
+ startFrom,
2801
+ limit
2802
+ };
2803
+ const _authRequest = await this._options.authProvider.getAuthRequest();
2804
+ const _headers = mergeHeaders(
2805
+ _authRequest.headers,
2806
+ this._options?.headers,
2807
+ requestOptions?.headers
2808
+ );
2809
+ const _response = await fetcher({
2810
+ url: url_exports.join(
2811
+ await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
2812
+ `v1/agents/${url_exports.encodePathParam(id)}/versions`
2813
+ ),
2814
+ method: "GET",
2815
+ headers: _headers,
2816
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
2817
+ timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
2818
+ maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
2819
+ abortSignal: requestOptions?.abortSignal,
2820
+ fetchFn: this._options?.fetch,
2821
+ logging: this._options.logging
2822
+ });
2823
+ if (_response.ok) {
2824
+ return { data: _response.body, rawResponse: _response.rawResponse };
2825
+ }
2826
+ if (_response.error.reason === "status-code") {
2827
+ switch (_response.error.statusCode) {
2828
+ case 403:
2829
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
2830
+ case 404:
2831
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
2832
+ default:
2833
+ throw new VectrosError({
2834
+ statusCode: _response.error.statusCode,
2835
+ body: _response.error.body,
2836
+ rawResponse: _response.rawResponse
2837
+ });
2838
+ }
2839
+ }
2840
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/agents/{id}/versions");
2841
+ }
2842
+ /**
2843
+ * Stops a run. The answer is `202` with the run still `RUNNING`: read it with `GET /v1/runs/{id}` to see it end. A model call in progress is cut within a few seconds; a tool call in progress is first allowed to finish, for up to about 30 seconds, so its change is recorded and billed, and the run stops as soon as it has. The run then ends `CANCELLED` with `errorCode` `CANCELLED_BY_CALLER`, unless it had already completed, in which case it stays `COMPLETED`. Its reservation is settled once, like any run's: a model call in progress when it stopped is charged up to its maximum. A run that has ended (or that had not started, which this cancel ends) answers `200` with its final state, so a cancel can always be retried. A run can be cancelled by the credential that started it (for a token bound to a user, by that user) and by your root key. Requires the `runs:c` scope; with `runs:r` as well the answer is the whole run, otherwise only its `id`, `status`, `terminal`, `reason` and `errorCode`. Takes no body.
2844
+ *
2845
+ * @param {Vectros.CancelRunRequest} request
2846
+ * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration.
2847
+ *
2848
+ * @throws {@link Vectros.BadRequestError}
2849
+ * @throws {@link Vectros.UnauthorizedError}
2850
+ * @throws {@link Vectros.ForbiddenError}
2851
+ * @throws {@link Vectros.NotFoundError}
2852
+ * @throws {@link Vectros.TooManyRequestsError}
2853
+ *
2854
+ * @example
2855
+ * await client.agents.cancelRun({
2856
+ * id: "id"
2857
+ * })
2858
+ */
2859
+ cancelRun(request, requestOptions) {
2860
+ return HttpResponsePromise.fromPromise(this.__cancelRun(request, requestOptions));
2861
+ }
2862
+ async __cancelRun(request, requestOptions) {
2863
+ const { id, contextId } = request;
2864
+ const _queryParams = {
2865
+ contextId
2866
+ };
2867
+ const _authRequest = await this._options.authProvider.getAuthRequest();
2868
+ const _headers = mergeHeaders(
2869
+ _authRequest.headers,
2870
+ this._options?.headers,
2871
+ requestOptions?.headers
2872
+ );
2873
+ const _response = await fetcher({
2874
+ url: url_exports.join(
2875
+ await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
2876
+ `v1/runs/${url_exports.encodePathParam(id)}/cancel`
2877
+ ),
2878
+ method: "POST",
2879
+ headers: _headers,
2880
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
2881
+ timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
2882
+ maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
2883
+ abortSignal: requestOptions?.abortSignal,
2884
+ fetchFn: this._options?.fetch,
2885
+ logging: this._options.logging
2886
+ });
2887
+ if (_response.ok) {
2888
+ return { data: _response.body, rawResponse: _response.rawResponse };
2889
+ }
2890
+ if (_response.error.reason === "status-code") {
2891
+ switch (_response.error.statusCode) {
2892
+ case 400:
2893
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
2894
+ case 401:
2895
+ throw new UnauthorizedError(_response.error.body, _response.rawResponse);
2896
+ case 403:
2897
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
2898
+ case 404:
2899
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
2900
+ case 429:
2901
+ throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
2902
+ default:
2903
+ throw new VectrosError({
2904
+ statusCode: _response.error.statusCode,
2905
+ body: _response.error.body,
2906
+ rawResponse: _response.rawResponse
2907
+ });
2908
+ }
2909
+ }
2910
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/runs/{id}/cancel");
2911
+ }
2912
+ /**
2913
+ * Returns the status and metadata of one run: the agent version that ran, how it ended, its tool calls (never their arguments or results) and what it was charged. It never returns text: the answer is delivered only in the run's stream. A run is visible to the credential that started it (for a token bound to a user, to that user) and to your root key, and is kept for 30 days after it ends. Requires the `runs:r` scope.
2914
+ *
2915
+ * @param {Vectros.GetRunRequest} request
2916
+ * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration.
2917
+ *
2918
+ * @throws {@link Vectros.BadRequestError}
2919
+ * @throws {@link Vectros.UnauthorizedError}
2920
+ * @throws {@link Vectros.ForbiddenError}
2921
+ * @throws {@link Vectros.NotFoundError}
2922
+ *
2923
+ * @example
2924
+ * await client.agents.getRun({
2925
+ * id: "id"
2926
+ * })
2927
+ */
2928
+ getRun(request, requestOptions) {
2929
+ return HttpResponsePromise.fromPromise(this.__getRun(request, requestOptions));
2930
+ }
2931
+ async __getRun(request, requestOptions) {
2932
+ const { id, contextId } = request;
2933
+ const _queryParams = {
2934
+ contextId
2935
+ };
2936
+ const _authRequest = await this._options.authProvider.getAuthRequest();
2937
+ const _headers = mergeHeaders(
2938
+ _authRequest.headers,
2939
+ this._options?.headers,
2940
+ requestOptions?.headers
2941
+ );
2942
+ const _response = await fetcher({
2943
+ url: url_exports.join(
2944
+ await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
2945
+ `v1/runs/${url_exports.encodePathParam(id)}`
2946
+ ),
2947
+ method: "GET",
2948
+ headers: _headers,
2949
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
2950
+ timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
2951
+ maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
2952
+ abortSignal: requestOptions?.abortSignal,
2953
+ fetchFn: this._options?.fetch,
2954
+ logging: this._options.logging
2955
+ });
2956
+ if (_response.ok) {
2957
+ return { data: _response.body, rawResponse: _response.rawResponse };
2958
+ }
2959
+ if (_response.error.reason === "status-code") {
2960
+ switch (_response.error.statusCode) {
2961
+ case 400:
2962
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
2963
+ case 401:
2964
+ throw new UnauthorizedError(_response.error.body, _response.rawResponse);
2965
+ case 403:
2966
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
2967
+ case 404:
2968
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
2969
+ default:
2970
+ throw new VectrosError({
2971
+ statusCode: _response.error.statusCode,
2972
+ body: _response.error.body,
2973
+ rawResponse: _response.rawResponse
2974
+ });
2975
+ }
2976
+ }
2977
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/runs/{id}");
2247
2978
  }
2248
2979
  /**
2249
- * Returns the assembled query string (without the leading `?`).
2250
- * Returns an empty string when no parameters were added.
2980
+ * Starts a run of a stored agent and streams what it does as Server-Sent Events. The response is always `text/event-stream`, whatever `Accept` you send; its `X-Vectros-Run-Id` header names the run. The run's tool calls act as you, with your own permissions, and only through the tools the agent lists. On a prepaid account the run reserves its budget from your inference balance when it starts and returns what its model calls did not use when it ends; a fixed fee per run, tool calls and run time are billed separately, against your plan. Read each event's `type`; ignore types and fields you do not know; stop at the event with `terminal: true`. A stream that ends without one: read the run with `GET /v1/runs/{id}`. Closing the stream stops the run only on a best-effort basis. Requires the `runs:c` scope, and agent runs switched on for your tenant by an account owner.
2251
2981
  */
2252
- build() {
2253
- return [...this.parts.values()].join("&");
2254
- }
2255
- };
2256
- var TOKEN_PARAM = "token";
2257
- var BearerAuthProvider = class _BearerAuthProvider {
2258
- constructor(options) {
2259
- this.options = options;
2260
- }
2261
- static canCreate(options) {
2262
- return options?.[TOKEN_PARAM] != null;
2263
- }
2264
- async getAuthRequest({
2265
- endpointMetadata
2266
- } = {}) {
2267
- const token = await Supplier.get(this.options[TOKEN_PARAM]);
2268
- if (token == null) {
2269
- throw new VectrosError({
2270
- message: _BearerAuthProvider.AUTH_CONFIG_ERROR_MESSAGE
2271
- });
2272
- }
2273
- return {
2274
- headers: { Authorization: `Bearer ${token}` }
2275
- };
2276
- }
2277
- };
2278
- ((BearerAuthProvider2) => {
2279
- BearerAuthProvider2.AUTH_SCHEME = "BearerAuth";
2280
- BearerAuthProvider2.AUTH_CONFIG_ERROR_MESSAGE = `Please provide '${TOKEN_PARAM}' when initializing the client`;
2281
- function createInstance(options) {
2282
- return new BearerAuthProvider2(options);
2283
- }
2284
- BearerAuthProvider2.createInstance = createInstance;
2285
- })(BearerAuthProvider || (BearerAuthProvider = {}));
2286
- function mergeHeaders(...headersArray) {
2287
- const result = {};
2288
- for (const [key, value] of headersArray.filter((headers) => headers != null).flatMap((headers) => Object.entries(headers))) {
2289
- const insensitiveKey = key.toLowerCase();
2290
- if (value != null) {
2291
- result[insensitiveKey] = value;
2292
- } else if (insensitiveKey in result) {
2293
- delete result[insensitiveKey];
2294
- }
2295
- }
2296
- return result;
2297
- }
2298
- function mergeOnlyDefinedHeaders(...headersArray) {
2299
- const result = {};
2300
- for (const [key, value] of headersArray.filter((headers) => headers != null).flatMap((headers) => Object.entries(headers))) {
2301
- const insensitiveKey = key.toLowerCase();
2302
- if (value != null) {
2303
- result[insensitiveKey] = value;
2304
- }
2305
- }
2306
- return result;
2307
- }
2308
- function normalizeClientOptions(options) {
2309
- const headers = mergeHeaders(
2310
- {
2311
- "X-Fern-Language": "JavaScript",
2312
- "X-Fern-Runtime": RUNTIME.type,
2313
- "X-Fern-Runtime-Version": RUNTIME.version
2314
- },
2315
- options?.headers
2316
- );
2317
- return {
2318
- ...options,
2319
- logging: logging_exports.createLogger(options?.logging),
2320
- headers
2321
- };
2322
- }
2323
- function normalizeClientOptionsWithAuth(options) {
2324
- const normalized = normalizeClientOptions(options);
2325
- if (options.auth === false) {
2326
- normalized.authProvider = new NoOpAuthProvider();
2327
- return normalized;
2982
+ createRun(request, requestOptions) {
2983
+ return HttpResponsePromise.fromPromise(this.__createRun(request, requestOptions));
2328
2984
  }
2329
- if (options.auth != null) {
2330
- if (typeof options.auth === "function") {
2331
- normalized.authProvider = { getAuthRequest: options.auth };
2332
- return normalized;
2985
+ async __createRun(request, requestOptions) {
2986
+ const { "Idempotency-Key": idempotencyKey, ..._body } = request;
2987
+ const _authRequest = await this._options.authProvider.getAuthRequest();
2988
+ const _headers = mergeHeaders(
2989
+ _authRequest.headers,
2990
+ this._options?.headers,
2991
+ mergeOnlyDefinedHeaders({ "Idempotency-Key": idempotencyKey }),
2992
+ requestOptions?.headers
2993
+ );
2994
+ const _response = await fetcher({
2995
+ url: url_exports.join(
2996
+ await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
2997
+ "v1/runs"
2998
+ ),
2999
+ method: "POST",
3000
+ headers: _headers,
3001
+ contentType: "application/json",
3002
+ queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
3003
+ requestType: "json",
3004
+ body: _body,
3005
+ responseType: "sse",
3006
+ timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
3007
+ maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
3008
+ abortSignal: requestOptions?.abortSignal,
3009
+ fetchFn: this._options?.fetch,
3010
+ logging: this._options.logging
3011
+ });
3012
+ if (_response.ok) {
3013
+ return {
3014
+ data: new Stream({
3015
+ stream: _response.body,
3016
+ parse: (data) => data,
3017
+ signal: requestOptions?.abortSignal,
3018
+ eventShape: {
3019
+ type: "sse"
3020
+ }
3021
+ }),
3022
+ rawResponse: _response.rawResponse
3023
+ };
2333
3024
  }
2334
- if (isAuthProvider(options.auth)) {
2335
- normalized.authProvider = options.auth;
2336
- return normalized;
3025
+ if (_response.error.reason === "status-code") {
3026
+ switch (_response.error.statusCode) {
3027
+ case 400:
3028
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
3029
+ case 401:
3030
+ throw new UnauthorizedError(_response.error.body, _response.rawResponse);
3031
+ case 402:
3032
+ throw new PaymentRequiredError(_response.error.body, _response.rawResponse);
3033
+ case 403:
3034
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
3035
+ case 404:
3036
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
3037
+ case 409:
3038
+ throw new ConflictError(_response.error.body, _response.rawResponse);
3039
+ case 413:
3040
+ throw new ContentTooLargeError(_response.error.body, _response.rawResponse);
3041
+ case 422:
3042
+ throw new UnprocessableEntityError(_response.error.body, _response.rawResponse);
3043
+ case 429:
3044
+ throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
3045
+ case 503:
3046
+ throw new ServiceUnavailableError(_response.error.body, _response.rawResponse);
3047
+ default:
3048
+ throw new VectrosError({
3049
+ statusCode: _response.error.statusCode,
3050
+ body: _response.error.body,
3051
+ rawResponse: _response.rawResponse
3052
+ });
3053
+ }
2337
3054
  }
2338
- Object.assign(normalized, options.auth);
2339
- }
2340
- const normalizedWithNoOpAuthProvider = withNoOpAuthProvider(normalized);
2341
- normalized.authProvider ?? (normalized.authProvider = new BearerAuthProvider(normalizedWithNoOpAuthProvider));
2342
- return normalized;
2343
- }
2344
- function withNoOpAuthProvider(options) {
2345
- return {
2346
- ...options,
2347
- authProvider: new NoOpAuthProvider()
2348
- };
2349
- }
2350
- function handleNonStatusCodeError(error, rawResponse, method, path2) {
2351
- switch (error.reason) {
2352
- case "non-json":
2353
- throw new VectrosError({
2354
- statusCode: error.statusCode,
2355
- body: error.rawBody,
2356
- rawResponse
2357
- });
2358
- case "body-is-null":
2359
- throw new VectrosError({
2360
- statusCode: error.statusCode,
2361
- rawResponse
2362
- });
2363
- case "timeout":
2364
- throw new VectrosTimeoutError(`Timeout exceeded when calling ${method} ${path2}.`, {
2365
- cause: error.cause
2366
- });
2367
- case "unknown":
2368
- throw new VectrosError({
2369
- message: error.errorMessage,
2370
- rawResponse,
2371
- cause: error.cause
2372
- });
2373
- default:
2374
- throw new VectrosError({
2375
- message: "Unknown error",
2376
- rawResponse
2377
- });
3055
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/runs");
2378
3056
  }
2379
- }
3057
+ };
2380
3058
  var AuthClient = class {
2381
3059
  constructor(options) {
2382
3060
  this._options = normalizeClientOptionsWithAuth(options);
@@ -2575,7 +3253,7 @@ var AuthClient = class {
2575
3253
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/admin/keys/scoped");
2576
3254
  }
2577
3255
  /**
2578
- * Creates a scoped API key (an `ssk_*` secret) that inherits its permissions from an existing access profile in your account. The call is idempotent on the combination of tenant, context, user, and key name: re-issuing the same request returns the existing key WITHOUT re-disclosing its raw secret. The raw key is returned ONLY in this response — store it securely, as it cannot be retrieved again. Requires the `keys:c` scope. If you use a scoped credential, `keys:c` alone is not sufficient: because the minted key is durably bound to the profile you name, the profile's effective scopes may not exceed your own, and you may only mint against a profile whose `identityOverrides` values your own identity holds. Minting a key bound to your OWN principal needs nothing further; minting one bound to a DIFFERENT principal additionally requires the `delegate-mint` capability (`granted_capabilities`) on your credential — without it the request is refused. A root API key (`sk_`) is exempt from all three bounds. The profile you name must be `active` AND the user you name must not be `SUSPENDED`: either is refused with `409`, and no root exemption applies to that. Both refusals stop ISSUANCE only. Suspending the profile additionally stops credentials already bound to it, within about five minutes; suspending the user does not stop their existing keys at all. A `PENDING` user is fine.
3256
+ * Creates a scoped API key (an `ssk_*` secret) that inherits its permissions from an existing access profile in your account. The call is idempotent on the combination of tenant, context, user, and key name: re-issuing the same request returns the existing key WITHOUT re-disclosing its raw secret. The raw key is returned ONLY in this response — store it securely, as it cannot be retrieved again. Requires the `keys:c` scope. If you use a scoped credential, `keys:c` alone is not sufficient: because the minted key is durably bound to the profile you name, the profile's effective scopes may not exceed your own, and you may only mint against a profile whose `identityOverrides` values your own identity holds. Minting a key bound to your OWN principal needs nothing further; minting one bound to a DIFFERENT principal additionally requires the `delegate-mint` capability (`granted_capabilities`) on your credential — without it the request is refused. A root API key (`sk_`) is exempt from all three bounds. The profile you name must be `active` AND the user you name must not be `SUSPENDED`: either is refused with `409`, and no root exemption applies to that. Both refusals stop ISSUANCE only. Suspending the profile or the user additionally stops credentials already bound to it, within about five minutes. A `PENDING` user is fine.
2579
3257
  *
2580
3258
  * @param {Vectros.CreateScopedKeyRequest} request
2581
3259
  * @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -2918,14 +3596,13 @@ var AuthClient = class {
2918
3596
  * @throws {@link Vectros.BadRequestError}
2919
3597
  * @throws {@link Vectros.ForbiddenError}
2920
3598
  * @throws {@link Vectros.NotFoundError}
3599
+ * @throws {@link Vectros.ConflictError}
2921
3600
  * @throws {@link Vectros.TooManyRequestsError}
2922
3601
  *
2923
3602
  * @example
2924
3603
  * await client.auth.createAccessProfile({
2925
3604
  * contextId: "contextId",
2926
- * body: {
2927
- * principalId: "usr_6ba7b810-9dad-11d1-80b4-00c04fd430c8"
2928
- * }
3605
+ * body: {}
2929
3606
  * })
2930
3607
  */
2931
3608
  createAccessProfile(request, requestOptions) {
@@ -2970,6 +3647,8 @@ var AuthClient = class {
2970
3647
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
2971
3648
  case 404:
2972
3649
  throw new NotFoundError(_response.error.body, _response.rawResponse);
3650
+ case 409:
3651
+ throw new ConflictError(_response.error.body, _response.rawResponse);
2973
3652
  case 429:
2974
3653
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
2975
3654
  default:
@@ -3053,14 +3732,13 @@ var AuthClient = class {
3053
3732
  * @throws {@link Vectros.BadRequestError}
3054
3733
  * @throws {@link Vectros.PaymentRequiredError}
3055
3734
  * @throws {@link Vectros.ForbiddenError}
3735
+ * @throws {@link Vectros.NotFoundError}
3736
+ * @throws {@link Vectros.ConflictError}
3056
3737
  * @throws {@link Vectros.TooManyRequestsError}
3057
3738
  *
3058
3739
  * @example
3059
3740
  * await client.auth.createAppContext({
3060
- * body: {
3061
- * contextId: "myapp",
3062
- * name: "My Internal App"
3063
- * }
3741
+ * body: {}
3064
3742
  * })
3065
3743
  */
3066
3744
  createAppContext(request, requestOptions) {
@@ -3105,6 +3783,10 @@ var AuthClient = class {
3105
3783
  throw new PaymentRequiredError(_response.error.body, _response.rawResponse);
3106
3784
  case 403:
3107
3785
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
3786
+ case 404:
3787
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
3788
+ case 409:
3789
+ throw new ConflictError(_response.error.body, _response.rawResponse);
3108
3790
  case 429:
3109
3791
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
3110
3792
  default:
@@ -3193,18 +3875,13 @@ var AuthClient = class {
3193
3875
  * @throws {@link Vectros.BadRequestError}
3194
3876
  * @throws {@link Vectros.ForbiddenError}
3195
3877
  * @throws {@link Vectros.NotFoundError}
3878
+ * @throws {@link Vectros.ConflictError}
3196
3879
  * @throws {@link Vectros.TooManyRequestsError}
3197
3880
  *
3198
3881
  * @example
3199
3882
  * await client.auth.createRole({
3200
3883
  * contextId: "contextId",
3201
- * body: {
3202
- * roleId: "engineering-member",
3203
- * name: "Engineering Team Member",
3204
- * scopes: [{
3205
- * allowed_actions: ["records:cru", "search:r"]
3206
- * }]
3207
- * }
3884
+ * body: {}
3208
3885
  * })
3209
3886
  */
3210
3887
  createRole(request, requestOptions) {
@@ -3249,6 +3926,8 @@ var AuthClient = class {
3249
3926
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
3250
3927
  case 404:
3251
3928
  throw new NotFoundError(_response.error.body, _response.rawResponse);
3929
+ case 409:
3930
+ throw new ConflictError(_response.error.body, _response.rawResponse);
3252
3931
  case 429:
3253
3932
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
3254
3933
  default:
@@ -3339,15 +4018,14 @@ var AuthClient = class {
3339
4018
  * @throws {@link Vectros.BadRequestError}
3340
4019
  * @throws {@link Vectros.ForbiddenError}
3341
4020
  * @throws {@link Vectros.NotFoundError}
4021
+ * @throws {@link Vectros.ConflictError}
3342
4022
  * @throws {@link Vectros.TooManyRequestsError}
3343
4023
  *
3344
4024
  * @example
3345
4025
  * await client.auth.updateAccessProfile({
3346
4026
  * contextId: "contextId",
3347
4027
  * principalId: "principalId",
3348
- * body: {
3349
- * principalId: "usr_6ba7b810-9dad-11d1-80b4-00c04fd430c8"
3350
- * }
4028
+ * body: {}
3351
4029
  * })
3352
4030
  */
3353
4031
  updateAccessProfile(request, requestOptions) {
@@ -3389,6 +4067,8 @@ var AuthClient = class {
3389
4067
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
3390
4068
  case 404:
3391
4069
  throw new NotFoundError(_response.error.body, _response.rawResponse);
4070
+ case 409:
4071
+ throw new ConflictError(_response.error.body, _response.rawResponse);
3392
4072
  case 429:
3393
4073
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
3394
4074
  default:
@@ -3535,22 +4215,20 @@ var AuthClient = class {
3535
4215
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/app-contexts/{contextId}");
3536
4216
  }
3537
4217
  /**
3538
- * Updates an app context. This is a partial update: any field you omit (or send as null) keeps its existing value. The `contextId` is immutable and is taken from the URL path, so any `contextId` in the request body is ignored. Patchable fields: `name`, `description`, `companyName`; the per-principal metering trio (`meteringAxis`, `principalBurstLimit`, `principalUsageCap` — only takes effect for a partner with the corresponding account-level feature enabled); `readAccessLogDefault` (the PHI read-access-logging context default); and `identityProjectionClaims` (requires the platform provisioning capability on top of the ordinary scope below — see its own field description). Requires the `app-contexts:u` scope.
4218
+ * Updates an app context. This is a partial update: any field you omit (or send as null) keeps its existing value. The `contextId` is immutable and is taken from the URL path, so any `contextId` in the request body is ignored. Patchable fields: `name`, `description`, `companyName`; the per-principal metering trio (`meteringAxis`, `principalBurstLimit`, `principalUsageCap` — only takes effect for an account with the corresponding feature enabled); `readAccessLogDefault` (the PHI read-access-logging context default); and `identityProjectionClaims` (requires the platform provisioning capability on top of the ordinary scope below — see its own field description). Requires the `app-contexts:u` scope.
3539
4219
  *
3540
4220
  * @param {Vectros.UpdateAppContextRequest} request
3541
4221
  * @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
3542
4222
  *
3543
4223
  * @throws {@link Vectros.ForbiddenError}
3544
4224
  * @throws {@link Vectros.NotFoundError}
4225
+ * @throws {@link Vectros.ConflictError}
3545
4226
  * @throws {@link Vectros.TooManyRequestsError}
3546
4227
  *
3547
4228
  * @example
3548
4229
  * await client.auth.updateAppContext({
3549
4230
  * contextId: "contextId",
3550
- * body: {
3551
- * contextId: "myapp",
3552
- * name: "My Internal App"
3553
- * }
4231
+ * body: {}
3554
4232
  * })
3555
4233
  */
3556
4234
  updateAppContext(request, requestOptions) {
@@ -3590,6 +4268,8 @@ var AuthClient = class {
3590
4268
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
3591
4269
  case 404:
3592
4270
  throw new NotFoundError(_response.error.body, _response.rawResponse);
4271
+ case 409:
4272
+ throw new ConflictError(_response.error.body, _response.rawResponse);
3593
4273
  case 429:
3594
4274
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
3595
4275
  default:
@@ -3746,19 +4426,14 @@ var AuthClient = class {
3746
4426
  *
3747
4427
  * @throws {@link Vectros.ForbiddenError}
3748
4428
  * @throws {@link Vectros.NotFoundError}
4429
+ * @throws {@link Vectros.ConflictError}
3749
4430
  * @throws {@link Vectros.TooManyRequestsError}
3750
4431
  *
3751
4432
  * @example
3752
4433
  * await client.auth.updateRole({
3753
4434
  * contextId: "contextId",
3754
4435
  * roleId: "roleId",
3755
- * body: {
3756
- * roleId: "engineering-member",
3757
- * name: "Engineering Team Member",
3758
- * scopes: [{
3759
- * allowed_actions: ["records:cru", "search:r"]
3760
- * }]
3761
- * }
4436
+ * body: {}
3762
4437
  * })
3763
4438
  */
3764
4439
  updateRole(request, requestOptions) {
@@ -3798,6 +4473,8 @@ var AuthClient = class {
3798
4473
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
3799
4474
  case 404:
3800
4475
  throw new NotFoundError(_response.error.body, _response.rawResponse);
4476
+ case 409:
4477
+ throw new ConflictError(_response.error.body, _response.rawResponse);
3801
4478
  case 429:
3802
4479
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
3803
4480
  default:
@@ -3823,6 +4500,7 @@ var AuthClient = class {
3823
4500
  *
3824
4501
  * @throws {@link Vectros.ForbiddenError}
3825
4502
  * @throws {@link Vectros.NotFoundError}
4503
+ * @throws {@link Vectros.ConflictError}
3826
4504
  * @throws {@link Vectros.TooManyRequestsError}
3827
4505
  *
3828
4506
  * @example
@@ -3865,6 +4543,8 @@ var AuthClient = class {
3865
4543
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
3866
4544
  case 404:
3867
4545
  throw new NotFoundError(_response.error.body, _response.rawResponse);
4546
+ case 409:
4547
+ throw new ConflictError(_response.error.body, _response.rawResponse);
3868
4548
  case 429:
3869
4549
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
3870
4550
  default:
@@ -4146,6 +4826,7 @@ var AuthClient = class {
4146
4826
  * @throws {@link Vectros.BadRequestError}
4147
4827
  * @throws {@link Vectros.ForbiddenError}
4148
4828
  * @throws {@link Vectros.NotFoundError}
4829
+ * @throws {@link Vectros.ConflictError}
4149
4830
  * @throws {@link Vectros.TooManyRequestsError}
4150
4831
  *
4151
4832
  * @example
@@ -4192,6 +4873,8 @@ var AuthClient = class {
4192
4873
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
4193
4874
  case 404:
4194
4875
  throw new NotFoundError(_response.error.body, _response.rawResponse);
4876
+ case 409:
4877
+ throw new ConflictError(_response.error.body, _response.rawResponse);
4195
4878
  case 429:
4196
4879
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
4197
4880
  default:
@@ -4205,7 +4888,7 @@ var AuthClient = class {
4205
4888
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "PUT", "/v1/auth/issuers/{issuerId}");
4206
4889
  }
4207
4890
  /**
4208
- * Deregisters a trusted third-party IdP issuer. Requires a root API key or the bootstrap's provisioning capability. A credential confined to one app context may only deregister an issuer registered in that context; naming one registered in another context returns 404, identically to a nonexistent issuerId. A root API key may deregister any issuer. Refused if any user account was ever created or matched via this issuer (by a prior self-signup or accepted invite, through `POST /v1/auth/token/exchange`) — that access cannot be silently orphaned. This is unconditional on the affected users' `status`: suspending them first does not lift the refusal. **A bound registration cannot be replaced, self-service, within its own app context**: registering a replacement issuer under a different issuerId in the SAME context also fails, because the context's one-active-issuer claim is released only when THIS registration is deleted. Two real options: suspend this issuer (stops new exchanges immediately) and register a replacement under a DIFFERENT app context — note that targets a different context, so this context's existing users/roles/access profiles are not carried over; or contact your platform operator, who can force-release this registration so a replacement may be registered in the SAME context under a new issuerId. **The operator path is not a lighter-weight alternative to the first — it PERMANENTLY RETIRES this issuerId and leaves every bound user unable to ever exchange through it again; it does not preserve continuity for them any better than registering under a different context does.** An issuer that has never been used for an exchange (no bound users yet) can always be deregistered.
4891
+ * Deregisters a trusted third-party IdP issuer. Requires a root API key or the bootstrap's provisioning capability. A credential confined to one app context may only deregister an issuer registered in that context; naming one registered in another context returns 404, identically to a nonexistent issuerId. A root API key may deregister any issuer. Refused if any user account was ever created or matched via this issuer (by a prior self-signup or accepted invite, through `POST /v1/auth/token/exchange`) — that access cannot be silently orphaned. This is unconditional on the affected users' `status`: suspending them first does not lift the refusal. **A bound registration cannot be replaced, self-service, within its own app context**: registering a replacement issuer under a different issuerId in the SAME context also fails, because the context's one-active-issuer claim is released only when THIS registration is deleted. Two real options: suspend this issuer (stops new exchanges immediately) and register a replacement under a DIFFERENT app context — note that targets a different context, so this context's existing users/roles/access profiles are not carried over; or contact support, who can force-release this registration so a replacement may be registered in the SAME context under a new issuerId. **The support path is not a lighter-weight alternative to the first — it PERMANENTLY RETIRES this issuerId and leaves every bound user unable to ever exchange through it again; it does not preserve continuity for them any better than registering under a different context does.** An issuer that has never been used for an exchange (no bound users yet) can always be deregistered.
4209
4892
  *
4210
4893
  * @param {Vectros.DeleteIssuerRequest} request
4211
4894
  * @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -4331,7 +5014,7 @@ var AuthClient = class {
4331
5014
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/auth/issuers");
4332
5015
  }
4333
5016
  /**
4334
- * Registers a trusted third-party IdP issuer that BYO-IdP token exchange (`POST /v1/auth/token/exchange`) may accept a `subject_token` from. Requires a root API key or the CLI bootstrap's provisioning capability — never an ordinary partner-grantable scope. A credential authorized only via the provisioning capability may register only against the app context it is bound to; naming a different one returns 403. A root API key is unaffected and may register against any of its contexts. A registration without `restrictedToDomain` is created `pending_verification` with a one-time challenge (`verificationClaim`, `verificationNonce`, `verificationExpiresAt`) and accepts no token until you prove you control the issuer with `POST /v1/auth/issuers/{issuerId}/verify`; it claims no `(issuer, audience)` pair until then, so registering never reveals whether another tenant holds one. A registration scoped to an already-verified domain with `restrictedToDomain` is `active` at once. Idempotent by `issuerId` within your tenant. If `issuerId` collides with a registration owned by a different app context than the one you're confined to, the request fails with 400 rather than returning that context's configuration. An app context may have at most one active issuer — deregister the existing one first if you need to replace it. One issuer MAY serve several contexts today, each via its own registration row with a distinct `audience`. Optionally name `restrictedToDomain` to scope this registration's (issuer, audience) uniqueness to a specific VERIFIED domain rather than the bare pair — see that field's own description. A domain-scoped registration proves control of the DOMAIN, not of the issuer itself: it routes only tokens carrying that domain's `hd` claim.
5017
+ * Registers a trusted third-party IdP issuer that BYO-IdP token exchange (`POST /v1/auth/token/exchange`) may accept a `subject_token` from. Requires a root API key or the CLI bootstrap's provisioning capability — never an ordinary grantable scope. A credential authorized only via the provisioning capability may register only against the app context it is bound to; naming a different one returns 403. A root API key is unaffected and may register against any of its contexts. A registration without `restrictedToDomain` is created `pending_verification` with a one-time challenge (`verificationClaim`, `verificationNonce`, `verificationExpiresAt`) and accepts no token until you prove you control the issuer with `POST /v1/auth/issuers/{issuerId}/verify`; it claims no `(issuer, audience)` pair until then, so registering never reveals whether another tenant holds one. A registration scoped to an already-verified domain with `restrictedToDomain` is `active` at once. Idempotent by `issuerId` within your tenant. If `issuerId` collides with a registration owned by a different app context than the one you're confined to, the request fails with 400 rather than returning that context's configuration. An app context may have at most one active issuer — deregister the existing one first if you need to replace it. One issuer MAY serve several contexts, each via its own registration row with a distinct `audience`. Optionally name `restrictedToDomain` to scope this registration's (issuer, audience) uniqueness to a specific VERIFIED domain rather than the bare pair — see that field's own description. A domain-scoped registration proves control of the DOMAIN, not of the issuer itself: it routes only tokens carrying that domain's `hd` claim.
4335
5018
  *
4336
5019
  * @param {Vectros.IssuerRequest} request
4337
5020
  * @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -4740,6 +5423,7 @@ var AuthClient = class {
4740
5423
  * @throws {@link Vectros.BadRequestError}
4741
5424
  * @throws {@link Vectros.ForbiddenError}
4742
5425
  * @throws {@link Vectros.NotFoundError}
5426
+ * @throws {@link Vectros.ConflictError}
4743
5427
  * @throws {@link Vectros.TooManyRequestsError}
4744
5428
  *
4745
5429
  * @example
@@ -4787,6 +5471,8 @@ var AuthClient = class {
4787
5471
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
4788
5472
  case 404:
4789
5473
  throw new NotFoundError(_response.error.body, _response.rawResponse);
5474
+ case 409:
5475
+ throw new ConflictError(_response.error.body, _response.rawResponse);
4790
5476
  case 429:
4791
5477
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
4792
5478
  default:
@@ -4886,6 +5572,7 @@ var AuthClient = class {
4886
5572
  * @throws {@link Vectros.UnauthorizedError}
4887
5573
  * @throws {@link Vectros.ForbiddenError}
4888
5574
  * @throws {@link Vectros.NotFoundError}
5575
+ * @throws {@link Vectros.ContentTooLargeError}
4889
5576
  * @throws {@link Vectros.TooManyRequestsError}
4890
5577
  *
4891
5578
  * @example
@@ -4930,6 +5617,8 @@ var AuthClient = class {
4930
5617
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
4931
5618
  case 404:
4932
5619
  throw new NotFoundError(_response.error.body, _response.rawResponse);
5620
+ case 413:
5621
+ throw new ContentTooLargeError(_response.error.body, _response.rawResponse);
4933
5622
  case 429:
4934
5623
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
4935
5624
  default:
@@ -5069,7 +5758,7 @@ var ComplianceClient = class {
5069
5758
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/erasure-requests/{id}");
5070
5759
  }
5071
5760
  /**
5072
- * Submits an asynchronous job to export your account's data, or a single end-subject's data, across the requested contexts. The request returns 202 with an `exportJobId`; poll `GET /v1/admin/export/{id}` until the job completes to obtain a short-lived presigned download URL and a manifest describing the payload. Requires a root API key — a scoped credential is rejected with 403.
5761
+ * Reserved: with a root API key this operation answers `501` and starts no job. The request and response shapes are published so that integrations can be written against them: a request names the contexts, or a single end-subject, to export, and the response carries an `exportJobId` that `GET /v1/admin/export/{id}` reports on. Requires a root API key — a scoped credential is rejected with 403.
5073
5762
  *
5074
5763
  * @param {Vectros.ExportRequest} request
5075
5764
  * @param {ComplianceClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -5130,7 +5819,7 @@ var ComplianceClient = class {
5130
5819
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/admin/export");
5131
5820
  }
5132
5821
  /**
5133
- * Polls an export job by id. While the job is still running this returns its status only; once it completes, the response also includes a short-lived presigned download URL and a manifest (format version and per-context counts). Requires a root API key.
5822
+ * Reserved: with a root API key this operation answers `501`. Its response shape is the one the export operation above refers to: the job status, and a short-lived presigned download URL and a manifest (format version and per-context counts) for a completed job. Requires a root API key.
5134
5823
  *
5135
5824
  * @param {Vectros.GetExportRequest} request
5136
5825
  * @param {ComplianceClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -5196,7 +5885,7 @@ var DocumentsClient = class {
5196
5885
  this._options = normalizeClientOptionsWithAuth(options);
5197
5886
  }
5198
5887
  /**
5199
- * Returns a paginated list of your documents, optionally filtered by folder (`folderId`) and/or owner (`userId` or `scope`). The response is a `{data, nextCursor}` envelope; pass `nextCursor` back as `startFrom` to fetch the next page. Requires the `documents:r` scope.
5888
+ * Returns a paginated list of your documents, optionally filtered by folder (`folderId`), owner (`userId` or `scope`) and/or type (`type`). The response is a `{data, nextCursor}` envelope; pass `nextCursor` back as `startFrom` to fetch the next page. A page can hold fewer documents than `limit`, or none, while `nextCursor` is still set: keep paging until `nextCursor` is null. Requires the `documents:r` scope.
5200
5889
  *
5201
5890
  * @param {Vectros.ListDocumentsRequest} request
5202
5891
  * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -5206,6 +5895,7 @@ var DocumentsClient = class {
5206
5895
  * userId: "550e8400-e29b-41d4-a716-446655440000",
5207
5896
  * scope: "group:eng-team",
5208
5897
  * folderId: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
5898
+ * type: "investigation_report",
5209
5899
  * startFrom: "b3BhcXVlLWN1cnNvci1mcm9tLXRoZS1wcmV2aW91cy1wYWdl"
5210
5900
  * })
5211
5901
  */
@@ -5213,11 +5903,12 @@ var DocumentsClient = class {
5213
5903
  return HttpResponsePromise.fromPromise(this.__listDocuments(request, requestOptions));
5214
5904
  }
5215
5905
  async __listDocuments(request = {}, requestOptions) {
5216
- const { userId, scope, folderId, startFrom, limit } = request;
5906
+ const { userId, scope, folderId, type: type_, startFrom, limit } = request;
5217
5907
  const _queryParams = {
5218
5908
  userId,
5219
5909
  scope,
5220
5910
  folderId,
5911
+ type: type_,
5221
5912
  startFrom,
5222
5913
  limit
5223
5914
  };
@@ -5261,13 +5952,13 @@ var DocumentsClient = class {
5261
5952
  *
5262
5953
  * @throws {@link Vectros.BadRequestError}
5263
5954
  * @throws {@link Vectros.ForbiddenError}
5955
+ * @throws {@link Vectros.NotFoundError}
5956
+ * @throws {@link Vectros.ConflictError}
5264
5957
  * @throws {@link Vectros.TooManyRequestsError}
5265
5958
  *
5266
5959
  * @example
5267
5960
  * await client.documents.ingestDocument({
5268
- * body: {
5269
- * title: "Patient Intake Form \u2014 Jane Doe"
5270
- * }
5961
+ * body: {}
5271
5962
  * })
5272
5963
  */
5273
5964
  ingestDocument(request, requestOptions) {
@@ -5312,6 +6003,10 @@ var DocumentsClient = class {
5312
6003
  throw new BadRequestError(_response.error.body, _response.rawResponse);
5313
6004
  case 403:
5314
6005
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
6006
+ case 404:
6007
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
6008
+ case 409:
6009
+ throw new ConflictError(_response.error.body, _response.rawResponse);
5315
6010
  case 429:
5316
6011
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
5317
6012
  default:
@@ -5393,9 +6088,7 @@ var DocumentsClient = class {
5393
6088
  * @example
5394
6089
  * await client.documents.updateDocument({
5395
6090
  * id: "id",
5396
- * body: {
5397
- * title: "Patient Intake Form \u2014 Jane Doe"
5398
- * }
6091
+ * body: {}
5399
6092
  * })
5400
6093
  */
5401
6094
  updateDocument(request, requestOptions) {
@@ -5459,6 +6152,7 @@ var DocumentsClient = class {
5459
6152
  * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
5460
6153
  *
5461
6154
  * @throws {@link Vectros.NotFoundError}
6155
+ * @throws {@link Vectros.ConflictError}
5462
6156
  * @throws {@link Vectros.TooManyRequestsError}
5463
6157
  *
5464
6158
  * @example
@@ -5498,6 +6192,8 @@ var DocumentsClient = class {
5498
6192
  switch (_response.error.statusCode) {
5499
6193
  case 404:
5500
6194
  throw new NotFoundError(_response.error.body, _response.rawResponse);
6195
+ case 409:
6196
+ throw new ConflictError(_response.error.body, _response.rawResponse);
5501
6197
  case 429:
5502
6198
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
5503
6199
  default:
@@ -5790,11 +6486,12 @@ var DocumentsClient = class {
5790
6486
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/documents/{id}/download");
5791
6487
  }
5792
6488
  /**
5793
- * Returns the document's full text body when it is retained: always available for text-ingested documents, and for file-uploaded documents unless they were uploaded with `storeText=false` (which discards the extracted text once indexing completes — the original file remains available via `GET /{id}/download`). Returns 404 when the document does not exist, its text was not retained, or extraction has not yet completed. Requires the `documents:r` scope.
6489
+ * Returns the document's full text body when it is retained: retained for text-ingested documents, and for file-uploaded documents unless they were uploaded with `storeText=false` (which discards the extracted text once indexing completes — the original file remains available via `GET /v1/documents/{id}/download`). Returns 404 when the document does not exist, its text was not retained, extraction has not yet completed, or no text could be extracted from its file (see the document's `extraction`). To read a long text in parts, pass `limit` (and `offset` from the second part on): offsets and lengths count Unicode characters (code points), `totalLength` is the length of the whole text, and `nextOffset` is where the next part starts, absent once the end is reached. Requires the `documents:r` scope.
5794
6490
  *
5795
6491
  * @param {Vectros.GetDocumentTextRequest} request
5796
6492
  * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
5797
6493
  *
6494
+ * @throws {@link Vectros.BadRequestError}
5798
6495
  * @throws {@link Vectros.NotFoundError}
5799
6496
  *
5800
6497
  * @example
@@ -5806,7 +6503,11 @@ var DocumentsClient = class {
5806
6503
  return HttpResponsePromise.fromPromise(this.__getDocumentText(request, requestOptions));
5807
6504
  }
5808
6505
  async __getDocumentText(request, requestOptions) {
5809
- const { id } = request;
6506
+ const { id, offset, limit } = request;
6507
+ const _queryParams = {
6508
+ offset,
6509
+ limit
6510
+ };
5810
6511
  const _authRequest = await this._options.authProvider.getAuthRequest();
5811
6512
  const _headers = mergeHeaders(
5812
6513
  _authRequest.headers,
@@ -5820,7 +6521,7 @@ var DocumentsClient = class {
5820
6521
  ),
5821
6522
  method: "GET",
5822
6523
  headers: _headers,
5823
- queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
6524
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
5824
6525
  timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
5825
6526
  maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
5826
6527
  abortSignal: requestOptions?.abortSignal,
@@ -5832,6 +6533,8 @@ var DocumentsClient = class {
5832
6533
  }
5833
6534
  if (_response.error.reason === "status-code") {
5834
6535
  switch (_response.error.statusCode) {
6536
+ case 400:
6537
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
5835
6538
  case 404:
5836
6539
  throw new NotFoundError(_response.error.body, _response.rawResponse);
5837
6540
  default:
@@ -5910,6 +6613,7 @@ var DocumentsClient = class {
5910
6613
  *
5911
6614
  * @throws {@link Vectros.BadRequestError}
5912
6615
  * @throws {@link Vectros.ForbiddenError}
6616
+ * @throws {@link Vectros.ConflictError}
5913
6617
  * @throws {@link Vectros.TooManyRequestsError}
5914
6618
  *
5915
6619
  * @example
@@ -5959,6 +6663,8 @@ var DocumentsClient = class {
5959
6663
  throw new BadRequestError(_response.error.body, _response.rawResponse);
5960
6664
  case 403:
5961
6665
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
6666
+ case 409:
6667
+ throw new ConflictError(_response.error.body, _response.rawResponse);
5962
6668
  case 429:
5963
6669
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
5964
6670
  default:
@@ -6042,13 +6748,13 @@ var FoldersClient = class {
6042
6748
  *
6043
6749
  * @throws {@link Vectros.BadRequestError}
6044
6750
  * @throws {@link Vectros.ForbiddenError}
6751
+ * @throws {@link Vectros.NotFoundError}
6752
+ * @throws {@link Vectros.ConflictError}
6045
6753
  * @throws {@link Vectros.TooManyRequestsError}
6046
6754
  *
6047
6755
  * @example
6048
6756
  * await client.folders.createFolder({
6049
- * body: {
6050
- * name: "Patient Records 2024"
6051
- * }
6757
+ * body: {}
6052
6758
  * })
6053
6759
  */
6054
6760
  createFolder(request, requestOptions) {
@@ -6091,6 +6797,10 @@ var FoldersClient = class {
6091
6797
  throw new BadRequestError(_response.error.body, _response.rawResponse);
6092
6798
  case 403:
6093
6799
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
6800
+ case 404:
6801
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
6802
+ case 409:
6803
+ throw new ConflictError(_response.error.body, _response.rawResponse);
6094
6804
  case 429:
6095
6805
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
6096
6806
  default:
@@ -6166,14 +6876,13 @@ var FoldersClient = class {
6166
6876
  *
6167
6877
  * @throws {@link Vectros.ForbiddenError}
6168
6878
  * @throws {@link Vectros.NotFoundError}
6879
+ * @throws {@link Vectros.ConflictError}
6169
6880
  * @throws {@link Vectros.TooManyRequestsError}
6170
6881
  *
6171
6882
  * @example
6172
6883
  * await client.folders.updateFolder({
6173
6884
  * id: "id",
6174
- * body: {
6175
- * name: "Patient Records 2024"
6176
- * }
6885
+ * body: {}
6177
6886
  * })
6178
6887
  */
6179
6888
  updateFolder(request, requestOptions) {
@@ -6213,6 +6922,8 @@ var FoldersClient = class {
6213
6922
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
6214
6923
  case 404:
6215
6924
  throw new NotFoundError(_response.error.body, _response.rawResponse);
6925
+ case 409:
6926
+ throw new ConflictError(_response.error.body, _response.rawResponse);
6216
6927
  case 429:
6217
6928
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
6218
6929
  default:
@@ -6233,6 +6944,7 @@ var FoldersClient = class {
6233
6944
  *
6234
6945
  * @throws {@link Vectros.BadRequestError}
6235
6946
  * @throws {@link Vectros.NotFoundError}
6947
+ * @throws {@link Vectros.ConflictError}
6236
6948
  * @throws {@link Vectros.TooManyRequestsError}
6237
6949
  *
6238
6950
  * @example
@@ -6274,6 +6986,8 @@ var FoldersClient = class {
6274
6986
  throw new BadRequestError(_response.error.body, _response.rawResponse);
6275
6987
  case 404:
6276
6988
  throw new NotFoundError(_response.error.body, _response.rawResponse);
6989
+ case 409:
6990
+ throw new ConflictError(_response.error.body, _response.rawResponse);
6277
6991
  case 429:
6278
6992
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
6279
6993
  default:
@@ -6287,7 +7001,7 @@ var FoldersClient = class {
6287
7001
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "DELETE", "/v1/folders/{id}");
6288
7002
  }
6289
7003
  /**
6290
- * Partially updates a folder using an RFC 7386 JSON Merge Patch. The `name`, `description`, and ownership fields (`userId`, `scopes`) are applied when present and left unchanged when omitted; sending any of these as null is rejected, because clearing a field is not supported in this release (omit it instead). `slug` and `parentFolderId` are immutable — a folder cannot be re-slugged or moved via the API — and the request is rejected if either is present. Pass `expectedVersion` for optimistic concurrency (you get a 409 if the folder changed since you last read it). Requires the `folders:u` scope.
7004
+ * Partially updates a folder using an RFC 7386 JSON Merge Patch. The `name`, `description`, and ownership fields (`userId`, `scopes`) are applied when present and left unchanged when omitted; sending any of these as null is rejected, because clearing a field is not supported (omit it instead). `slug` and `parentFolderId` are immutable — a folder cannot be re-slugged or moved via the API — and the request is rejected if either is present. Pass `expectedVersion` for optimistic concurrency (you get a 409 if the folder changed since you last read it). Requires the `folders:u` scope.
6291
7005
  *
6292
7006
  * @param {Vectros.PatchFolderRequest} request
6293
7007
  * @param {FoldersClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -6301,9 +7015,7 @@ var FoldersClient = class {
6301
7015
  * @example
6302
7016
  * await client.folders.patchFolder({
6303
7017
  * id: "id",
6304
- * body: {
6305
- * name: "Patient Records 2024"
6306
- * }
7018
+ * body: {}
6307
7019
  * })
6308
7020
  */
6309
7021
  patchFolder(request, requestOptions) {
@@ -6510,15 +7222,15 @@ var IdentityClient = class {
6510
7222
  *
6511
7223
  * @throws {@link Vectros.BadRequestError}
6512
7224
  * @throws {@link Vectros.ForbiddenError}
7225
+ * @throws {@link Vectros.NotFoundError}
7226
+ * @throws {@link Vectros.ConflictError}
6513
7227
  * @throws {@link Vectros.TooManyRequestsError}
6514
7228
  *
6515
7229
  * @example
6516
7230
  * await client.identity.createEntity({
6517
7231
  * namespace: "team",
6518
7232
  * contextId: "myapp",
6519
- * body: {
6520
- * externalId: "team_eng_platform"
6521
- * }
7233
+ * body: {}
6522
7234
  * })
6523
7235
  */
6524
7236
  createEntity(request, requestOptions) {
@@ -6562,6 +7274,10 @@ var IdentityClient = class {
6562
7274
  throw new BadRequestError(_response.error.body, _response.rawResponse);
6563
7275
  case 403:
6564
7276
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
7277
+ case 404:
7278
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
7279
+ case 409:
7280
+ throw new ConflictError(_response.error.body, _response.rawResponse);
6565
7281
  case 429:
6566
7282
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
6567
7283
  default:
@@ -6642,6 +7358,7 @@ var IdentityClient = class {
6642
7358
  *
6643
7359
  * @throws {@link Vectros.BadRequestError}
6644
7360
  * @throws {@link Vectros.NotFoundError}
7361
+ * @throws {@link Vectros.ConflictError}
6645
7362
  * @throws {@link Vectros.TooManyRequestsError}
6646
7363
  *
6647
7364
  * @example
@@ -6649,9 +7366,7 @@ var IdentityClient = class {
6649
7366
  * namespace: "team",
6650
7367
  * id: "id",
6651
7368
  * contextId: "myapp",
6652
- * body: {
6653
- * externalId: "team_eng_platform"
6654
- * }
7369
+ * body: {}
6655
7370
  * })
6656
7371
  */
6657
7372
  updateEntity(request, requestOptions) {
@@ -6694,6 +7409,8 @@ var IdentityClient = class {
6694
7409
  throw new BadRequestError(_response.error.body, _response.rawResponse);
6695
7410
  case 404:
6696
7411
  throw new NotFoundError(_response.error.body, _response.rawResponse);
7412
+ case 409:
7413
+ throw new ConflictError(_response.error.body, _response.rawResponse);
6697
7414
  case 429:
6698
7415
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
6699
7416
  default:
@@ -6713,6 +7430,7 @@ var IdentityClient = class {
6713
7430
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
6714
7431
  *
6715
7432
  * @throws {@link Vectros.NotFoundError}
7433
+ * @throws {@link Vectros.ConflictError}
6716
7434
  * @throws {@link Vectros.TooManyRequestsError}
6717
7435
  *
6718
7436
  * @example
@@ -6757,6 +7475,8 @@ var IdentityClient = class {
6757
7475
  switch (_response.error.statusCode) {
6758
7476
  case 404:
6759
7477
  throw new NotFoundError(_response.error.body, _response.rawResponse);
7478
+ case 409:
7479
+ throw new ConflictError(_response.error.body, _response.rawResponse);
6760
7480
  case 429:
6761
7481
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
6762
7482
  default:
@@ -6980,15 +7700,13 @@ var IdentityClient = class {
6980
7700
  *
6981
7701
  * @throws {@link Vectros.ForbiddenError}
6982
7702
  * @throws {@link Vectros.NotFoundError}
7703
+ * @throws {@link Vectros.ConflictError}
6983
7704
  * @throws {@link Vectros.TooManyRequestsError}
6984
7705
  *
6985
7706
  * @example
6986
7707
  * await client.identity.updateNamespace({
6987
7708
  * namespace: "team",
6988
- * body: {
6989
- * namespace: "team",
6990
- * specificityRank: 1500
6991
- * }
7709
+ * body: {}
6992
7710
  * })
6993
7711
  */
6994
7712
  updateNamespace(request, requestOptions) {
@@ -7031,6 +7749,8 @@ var IdentityClient = class {
7031
7749
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
7032
7750
  case 404:
7033
7751
  throw new NotFoundError(_response.error.body, _response.rawResponse);
7752
+ case 409:
7753
+ throw new ConflictError(_response.error.body, _response.rawResponse);
7034
7754
  case 429:
7035
7755
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
7036
7756
  default:
@@ -7051,6 +7771,7 @@ var IdentityClient = class {
7051
7771
  *
7052
7772
  * @throws {@link Vectros.ForbiddenError}
7053
7773
  * @throws {@link Vectros.NotFoundError}
7774
+ * @throws {@link Vectros.ConflictError}
7054
7775
  * @throws {@link Vectros.TooManyRequestsError}
7055
7776
  *
7056
7777
  * @example
@@ -7095,6 +7816,8 @@ var IdentityClient = class {
7095
7816
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
7096
7817
  case 404:
7097
7818
  throw new NotFoundError(_response.error.body, _response.rawResponse);
7819
+ case 409:
7820
+ throw new ConflictError(_response.error.body, _response.rawResponse);
7098
7821
  case 429:
7099
7822
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
7100
7823
  default:
@@ -7159,7 +7882,7 @@ var IdentityClient = class {
7159
7882
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/namespaces");
7160
7883
  }
7161
7884
  /**
7162
- * Registers a new scope namespace and declares whether its values resolve to identity entities (`entityBacked`). Also requires `specificityRank`, an explicit, account-unique position in the specificity order used to break recordType schema-resolution ties. Requires a root API key or one of the CLI bootstrap's two provisioning capabilities — never an ordinary partner-grantable scope. A bootstrap credential's registration is confined to its own app context UNLESS it additionally holds the tenant-wide namespace-provisioning capability and `contextId` is omitted, in which case it may register a TENANT-WIDE namespace (visible to every context). `org` and `client` are reserved names, registered the same way as any other namespace.
7885
+ * Registers a new scope namespace and declares whether its values resolve to identity entities (`entityBacked`). Also requires `specificityRank`, an explicit, account-unique position in the specificity order used to break recordType schema-resolution ties. Requires a root API key or one of the CLI bootstrap's two provisioning capabilities — never an ordinary grantable scope. A bootstrap credential's registration is confined to its own app context UNLESS it additionally holds the tenant-wide namespace-provisioning capability and `contextId` is omitted, in which case it may register a TENANT-WIDE namespace (visible to every context). `org` and `client` are reserved names, registered the same way as any other namespace.
7163
7886
  *
7164
7887
  * @param {Vectros.RegisterNamespaceRequest} request
7165
7888
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -7170,10 +7893,7 @@ var IdentityClient = class {
7170
7893
  *
7171
7894
  * @example
7172
7895
  * await client.identity.registerNamespace({
7173
- * body: {
7174
- * namespace: "team",
7175
- * specificityRank: 1500
7176
- * }
7896
+ * body: {}
7177
7897
  * })
7178
7898
  */
7179
7899
  registerNamespace(request, requestOptions) {
@@ -7301,13 +8021,12 @@ var IdentityClient = class {
7301
8021
  *
7302
8022
  * @throws {@link Vectros.BadRequestError}
7303
8023
  * @throws {@link Vectros.ForbiddenError}
8024
+ * @throws {@link Vectros.ConflictError}
7304
8025
  * @throws {@link Vectros.TooManyRequestsError}
7305
8026
  *
7306
8027
  * @example
7307
8028
  * await client.identity.createUser({
7308
- * body: {
7309
- * externalId: "usr_12345"
7310
- * }
8029
+ * body: {}
7311
8030
  * })
7312
8031
  */
7313
8032
  createUser(request, requestOptions) {
@@ -7350,6 +8069,8 @@ var IdentityClient = class {
7350
8069
  throw new BadRequestError(_response.error.body, _response.rawResponse);
7351
8070
  case 403:
7352
8071
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
8072
+ case 409:
8073
+ throw new ConflictError(_response.error.body, _response.rawResponse);
7353
8074
  case 429:
7354
8075
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
7355
8076
  default:
@@ -7418,21 +8139,21 @@ var IdentityClient = class {
7418
8139
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/users/{id}");
7419
8140
  }
7420
8141
  /**
7421
- * Updates mutable fields on an existing user (such as email, status, payload, or schema binding). The `type` field is immutable after creation, and `email` cannot be changed while an invitation to that user is still outstanding — revoke the invitation, or invite the new address instead. This endpoint also activates an invited user: a PUT that moves a PENDING user to ACTIVE and carries `inviteToken`, `externalSubject`, and `emailVerifiedAttestation=true` completes the invitation. **`externalSubject` set this way is NOT an authentication binding and does not enable sign-in anywhere** — not the Vectros DevPortal/Admin App/web apps, and not `/v1/auth/token/exchange` either; both are granted only by the invitee authenticating themselves. If the invitee needs dev-portal/web-app access, send them the invitation link and let them accept it directly. If the invitee needs to sign in via token exchange, have them redeem `inviteToken` themselves at `/v1/auth/token/exchange` with their own credential — Vectros verifies it there and computes its own value for this field from the verified credential. The value you send here is stored exactly as-is, with no normalization, and does NOT automatically match or deduplicate against what a later token-exchange sign-in computes for the same real-world identity. Call this endpoint directly only if you run your own backend and want Vectros to record which of your own users a given account corresponds to — treat this field as informational for that purpose, not as a way to pre-authorize sign-in. Requires the `users:u` scope.
8142
+ * Updates mutable fields on an existing user (such as email, status, payload, or schema binding). The `type` field is immutable after creation, and `email` cannot be changed while an invitation to that user is still outstanding — revoke the invitation, or invite the new address instead. This endpoint also activates an invited user: a PUT that moves a PENDING user to ACTIVE and carries `inviteToken`, `externalSubject`, and `emailVerifiedAttestation=true` completes the invitation. **`externalSubject` set this way is NOT an authentication binding and does not enable sign-in anywhere** — not the Vectros DevPortal/Admin App/web apps, and not `/v1/auth/token/exchange` either; both are granted only by the invitee authenticating themselves. A subject stored through `PUT /v1/users/{id}` does not make the person a member of your account: it is ignored for the tenant claims in sign-in tokens, the developer portal's memberships list and tenant switching, and an ownership transfer. To give such a person access, delete the user and invite them again; accepting the invitation binds the subject and counts it. If the invitee needs dev-portal/web-app access, send them the invitation link and let them accept it directly. If the invitee needs to sign in via token exchange, have them redeem `inviteToken` themselves at `/v1/auth/token/exchange` with their own credential — Vectros verifies it there and computes its own value for this field from the verified credential. The value you send here is stored exactly as-is, with no normalization, and does NOT automatically match or deduplicate against what a later token-exchange sign-in computes for the same real-world identity. Call this endpoint directly only if you run your own backend and want Vectros to record which of your own users a given account corresponds to — treat this field as informational for that purpose, not as a way to pre-authorize sign-in. Requires the `users:u` scope.
7422
8143
  *
7423
8144
  * @param {Vectros.UpdateUserRequest} request
7424
8145
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
7425
8146
  *
7426
8147
  * @throws {@link Vectros.BadRequestError}
8148
+ * @throws {@link Vectros.ForbiddenError}
7427
8149
  * @throws {@link Vectros.NotFoundError}
8150
+ * @throws {@link Vectros.ConflictError}
7428
8151
  * @throws {@link Vectros.TooManyRequestsError}
7429
8152
  *
7430
8153
  * @example
7431
8154
  * await client.identity.updateUser({
7432
8155
  * id: "550e8400-e29b-41d4-a716-446655440000",
7433
- * body: {
7434
- * externalId: "usr_12345"
7435
- * }
8156
+ * body: {}
7436
8157
  * })
7437
8158
  */
7438
8159
  updateUser(request, requestOptions) {
@@ -7470,8 +8191,12 @@ var IdentityClient = class {
7470
8191
  switch (_response.error.statusCode) {
7471
8192
  case 400:
7472
8193
  throw new BadRequestError(_response.error.body, _response.rawResponse);
8194
+ case 403:
8195
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
7473
8196
  case 404:
7474
8197
  throw new NotFoundError(_response.error.body, _response.rawResponse);
8198
+ case 409:
8199
+ throw new ConflictError(_response.error.body, _response.rawResponse);
7475
8200
  case 429:
7476
8201
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
7477
8202
  default:
@@ -7490,6 +8215,7 @@ var IdentityClient = class {
7490
8215
  * @param {Vectros.DeleteUserRequest} request
7491
8216
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
7492
8217
  *
8218
+ * @throws {@link Vectros.ForbiddenError}
7493
8219
  * @throws {@link Vectros.NotFoundError}
7494
8220
  * @throws {@link Vectros.ConflictError}
7495
8221
  * @throws {@link Vectros.TooManyRequestsError}
@@ -7529,6 +8255,8 @@ var IdentityClient = class {
7529
8255
  }
7530
8256
  if (_response.error.reason === "status-code") {
7531
8257
  switch (_response.error.statusCode) {
8258
+ case 403:
8259
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
7532
8260
  case 404:
7533
8261
  throw new NotFoundError(_response.error.body, _response.rawResponse);
7534
8262
  case 409:
@@ -7733,7 +8461,7 @@ var InferenceClient = class {
7733
8461
  this._options = normalizeClientOptionsWithAuth(options);
7734
8462
  }
7735
8463
  /**
7736
- * Returns every inference model available to you, including each model's context window, the plan tiers it's available on, and the exact credit rates charged per 1K input and output tokens. Use this to populate model pickers and to validate a request before calling `/v1/chat`, `/v1/rag`, or `/v1/documents/{id}/ask`.
8464
+ * Returns the whole platform model catalog, whatever your plan: `availableOn` names each model's plan tiers. Each entry also carries the context window and the credit rates per 1K input and output tokens: `regionPricing.base` for global-region requests, `regionPricing.us` for default requests, `longContext` for prompts over its threshold, and `cachePricing` for prompt-cache tokens on a model that has cache prices. A model reached through a `providerAlias` is not listed. Use this to populate model pickers and to validate a request before calling `/v1/chat`, `/v1/rag`, or `/v1/documents/{id}/ask`.
7737
8465
  *
7738
8466
  * @param {InferenceClient.RequestOptions} requestOptions - Request-specific configuration.
7739
8467
  *
@@ -7777,7 +8505,7 @@ var InferenceClient = class {
7777
8505
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/models");
7778
8506
  }
7779
8507
  /**
7780
- * Streams a model response as Server-Sent Events (SSE). Send the full conversation history in the `messages` array; a message with role `system` is extracted and used as the system prompt. Token cost is debited from your pre-paid inference balance (in cents), and a small per-call flat fee is debited from your monthly platform credit allowance. Requires the `inference:r` scope.
8508
+ * Streams a model response as Server-Sent Events (SSE). Send the full conversation history in the `messages` array; a message with role `system` is extracted and used as the system prompt. On a pre-paid account, token cost is debited from your inference balance; usage-billed accounts accrue it for post-billing. A request routed through your own `providerAlias` incurs no Vectros token cost. A per-call platform fee is charged to your monthly credit allowance, except when the call fails on the server side: 0.2 credits for a call of up to 60 seconds, then 1 credit per 5 minutes of the call's duration. Requires the `inference:r` scope.
7781
8509
  */
7782
8510
  chatInference(request, requestOptions) {
7783
8511
  return HttpResponsePromise.fromPromise(this.__chatInference(request, requestOptions));
@@ -7830,10 +8558,14 @@ var InferenceClient = class {
7830
8558
  throw new PaymentRequiredError(_response.error.body, _response.rawResponse);
7831
8559
  case 403:
7832
8560
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
8561
+ case 404:
8562
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
7833
8563
  case 413:
7834
8564
  throw new ContentTooLargeError(_response.error.body, _response.rawResponse);
7835
8565
  case 429:
7836
8566
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
8567
+ case 503:
8568
+ throw new ServiceUnavailableError(_response.error.body, _response.rawResponse);
7837
8569
  default:
7838
8570
  throw new VectrosError({
7839
8571
  statusCode: _response.error.statusCode,
@@ -7845,7 +8577,7 @@ var InferenceClient = class {
7845
8577
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/chat");
7846
8578
  }
7847
8579
  /**
7848
- * Loads a single document's extracted text, supplies it as context, and streams a model answer about it. The document must be fully indexed. If the document exceeds the 32K-token cap, the call returns 413 with no credits charged — use `POST /v1/rag` instead to answer over larger or multi-document collections. Requires the `inference:r` scope.
8580
+ * Loads a single document's extracted text, supplies it as context, and streams a model answer about it. The document must have finished processing and have text. If the document exceeds the 32K-token cap, the call returns 413 with no credits charged — use `POST /v1/rag` instead to answer over larger or multi-document collections. Requires the `inference:r` scope.
7849
8581
  */
7850
8582
  documentAsk(request, requestOptions) {
7851
8583
  return HttpResponsePromise.fromPromise(this.__documentAsk(request, requestOptions));
@@ -7907,6 +8639,8 @@ var InferenceClient = class {
7907
8639
  throw new ContentTooLargeError(_response.error.body, _response.rawResponse);
7908
8640
  case 429:
7909
8641
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
8642
+ case 503:
8643
+ throw new ServiceUnavailableError(_response.error.body, _response.rawResponse);
7910
8644
  default:
7911
8645
  throw new VectrosError({
7912
8646
  statusCode: _response.error.statusCode,
@@ -7971,12 +8705,16 @@ var InferenceClient = class {
7971
8705
  throw new PaymentRequiredError(_response.error.body, _response.rawResponse);
7972
8706
  case 403:
7973
8707
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
8708
+ case 404:
8709
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
7974
8710
  case 413:
7975
8711
  throw new ContentTooLargeError(_response.error.body, _response.rawResponse);
7976
8712
  case 429:
7977
8713
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
7978
8714
  case 500:
7979
8715
  throw new InternalServerError(_response.error.body, _response.rawResponse);
8716
+ case 503:
8717
+ throw new ServiceUnavailableError(_response.error.body, _response.rawResponse);
7980
8718
  default:
7981
8719
  throw new VectrosError({
7982
8720
  statusCode: _response.error.statusCode,
@@ -8054,7 +8792,7 @@ var RecordsClient = class {
8054
8792
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/records/batch-get");
8055
8793
  }
8056
8794
  /**
8057
- * Reserved endpoint for batch lookup and reference resolution. The published response shape correlates results to each input and carries a per-item status envelope. It currently returns 501 (not implemented). The documented 200 response schema is the stable shape this endpoint will use once available. Requires the `records:r` scope.
8795
+ * Reserved endpoint for batch lookup and reference resolution. With the `records:r` scope it answers 501 (not implemented). The published response shape correlates results to each input and carries a per-item status envelope. Requires the `records:r` scope.
8058
8796
  *
8059
8797
  * @param {Vectros.BatchLookupRequest} request
8060
8798
  * @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -8115,7 +8853,7 @@ var RecordsClient = class {
8115
8853
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/records/lookup/batch");
8116
8854
  }
8117
8855
  /**
8118
- * Writes up to 50 records (or 50 with `atomicity: all_or_nothing`) in a single request. Each item in `items` has exactly the same shape, and goes through exactly the same validation, authorization and idempotency rules, as the body of a single `POST /v1/records` — including schema validation, `externalId` idempotency, unique-field enforcement, and the `records:c:<type>` scope check, which is applied per item against that item's own record type. A batch is not a way to write a type your credential could not write one at a time.
8856
+ * Writes up to 50 records per request in `best_effort` mode and up to 50 with `atomicity: all_or_nothing`, in a single request. Each item in `items` has exactly the same shape, and goes through exactly the same validation, authorization and idempotency rules, as the body of a single `POST /v1/records` — including schema validation, `externalId` idempotency, unique-field enforcement, and the `records:c:<type>` scope check, which is applied per item against that item's own record type. A batch is not a way to write a type your credential could not write one at a time.
8119
8857
  *
8120
8858
  * `atomicity` selects how the batch commits. `best_effort` (the default) writes each item independently: some can succeed while others fail, and each item's own outcome is reported. `all_or_nothing` commits every item in one transaction — if any item fails, no record is created or updated at all, and every item that was itself fine reports `not_committed` while the ones that failed report why. Because the transaction is bounded by the number of underlying storage rows rather than by the number of records, a large `all_or_nothing` batch can be refused as too large to commit atomically even when it is within the item limit; the error says so, and nothing is written when it happens.
8121
8859
  *
@@ -8254,6 +8992,8 @@ var RecordsClient = class {
8254
8992
  *
8255
8993
  * @throws {@link Vectros.BadRequestError}
8256
8994
  * @throws {@link Vectros.ForbiddenError}
8995
+ * @throws {@link Vectros.NotFoundError}
8996
+ * @throws {@link Vectros.ConflictError}
8257
8997
  * @throws {@link Vectros.TooManyRequestsError}
8258
8998
  *
8259
8999
  * @example
@@ -8310,6 +9050,10 @@ var RecordsClient = class {
8310
9050
  throw new BadRequestError(_response.error.body, _response.rawResponse);
8311
9051
  case 403:
8312
9052
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
9053
+ case 404:
9054
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
9055
+ case 409:
9056
+ throw new ConflictError(_response.error.body, _response.rawResponse);
8313
9057
  case 429:
8314
9058
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
8315
9059
  default:
@@ -8458,6 +9202,7 @@ var RecordsClient = class {
8458
9202
  * @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
8459
9203
  *
8460
9204
  * @throws {@link Vectros.NotFoundError}
9205
+ * @throws {@link Vectros.ConflictError}
8461
9206
  * @throws {@link Vectros.TooManyRequestsError}
8462
9207
  *
8463
9208
  * @example
@@ -8497,6 +9242,8 @@ var RecordsClient = class {
8497
9242
  switch (_response.error.statusCode) {
8498
9243
  case 404:
8499
9244
  throw new NotFoundError(_response.error.body, _response.rawResponse);
9245
+ case 409:
9246
+ throw new ConflictError(_response.error.body, _response.rawResponse);
8500
9247
  case 429:
8501
9248
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
8502
9249
  default:
@@ -8510,7 +9257,7 @@ var RecordsClient = class {
8510
9257
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "DELETE", "/v1/records/{id}");
8511
9258
  }
8512
9259
  /**
8513
- * Partially updates a record using an RFC 7386 JSON Merge Patch. The `payload` object is deep-merged into the existing payload: keys you send overwrite (recursing into nested objects), a key set to null is deleted, and keys you omit are left unchanged — so you can change a single field without re-sending the rest (unlike the full-replacement PUT). Top-level fields (`status`, `folderId`, `userId`, `scopes`) are set when present and left unchanged when omitted; sending a top-level field as null is rejected (clearing a top-level field is not supported in this release — omit it instead). `typeName`, `schemaId`, `externalId`, and `indexMode` are immutable and rejected if present. The merged result is validated against the schema. Pass `expectedVersion` to make the patch conditional (optimistic concurrency, 409 on conflict). Requires the `records:u:<type>` scope.
9260
+ * Partially updates a record using an RFC 7386 JSON Merge Patch. The `payload` object is deep-merged into the existing payload: keys you send overwrite (recursing into nested objects), a key set to null is deleted, and keys you omit are left unchanged — so you can change a single field without re-sending the rest (unlike the full-replacement PUT). Top-level fields (`status`, `folderId`, `userId`, `scopes`) are set when present and left unchanged when omitted; sending a top-level field as null is rejected (clearing a top-level field is not supported — omit it instead). `typeName`, `schemaId`, `externalId`, and `indexMode` are immutable and rejected if present. The merged result is validated against the schema. Pass `expectedVersion` to make the patch conditional (optimistic concurrency, 409 on conflict). Requires the `records:u:<type>` scope.
8514
9261
  *
8515
9262
  * @param {Vectros.PatchRecordRequest} request
8516
9263
  * @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -8939,6 +9686,8 @@ var SchemasClient = class {
8939
9686
  *
8940
9687
  * @throws {@link Vectros.BadRequestError}
8941
9688
  * @throws {@link Vectros.ForbiddenError}
9689
+ * @throws {@link Vectros.NotFoundError}
9690
+ * @throws {@link Vectros.ConflictError}
8942
9691
  * @throws {@link Vectros.TooManyRequestsError}
8943
9692
  *
8944
9693
  * @example
@@ -8963,8 +9712,7 @@ var SchemasClient = class {
8963
9712
  * }],
8964
9713
  * capabilities: {
8965
9714
  * "auditHistory": true
8966
- * },
8967
- * allowedSurfaces: ["record"]
9715
+ * }
8968
9716
  * }
8969
9717
  * })
8970
9718
  */
@@ -9008,6 +9756,10 @@ var SchemasClient = class {
9008
9756
  throw new BadRequestError(_response.error.body, _response.rawResponse);
9009
9757
  case 403:
9010
9758
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
9759
+ case 404:
9760
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
9761
+ case 409:
9762
+ throw new ConflictError(_response.error.body, _response.rawResponse);
9011
9763
  case 429:
9012
9764
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
9013
9765
  default:
@@ -9090,11 +9842,7 @@ var SchemasClient = class {
9090
9842
  * @example
9091
9843
  * await client.schemas.updateSchema({
9092
9844
  * id: "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
9093
- * body: {
9094
- * typeName: "intake_form",
9095
- * displayName: "Client Intake Form",
9096
- * allowedSurfaces: ["record"]
9097
- * }
9845
+ * body: {}
9098
9846
  * })
9099
9847
  */
9100
9848
  updateSchema(request, requestOptions) {
@@ -9151,7 +9899,7 @@ var SchemasClient = class {
9151
9899
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "PUT", "/v1/schemas/{id}");
9152
9900
  }
9153
9901
  /**
9154
- * Permanently deletes a record schema. The request is refused with 409 if records of this type still exist — delete those records first, since every record must reference a live schema. The same applies to documents bound to this schema (for a schema declaring the `document` surface) — delete those documents first. A lineage base (a schema other schemas declare `basedOn`) also cannot be deleted while any such variant still exists — delete the variant schema(s) first. It is likewise refused while any trigger rule fires off this schema — delete those trigger rules first. Requires the `schemas:d` scope.
9902
+ * Permanently deletes a record schema. The request is refused with 409 if records of this type still exist — delete those records first, since every record must reference a live schema. The same applies to documents bound to this schema (for a schema declaring the `document` surface) — delete those documents first. A lineage base (a schema other schemas declare `basedOn`) also cannot be deleted while any such variant still exists — delete the variant schema(s) first. It is likewise refused while any trigger rule fires off this schema — delete those trigger rules first — and, for a schema declaring the `user` or `entity` surface, while any user or entity bound to it still exists. Requires the `schemas:d` scope.
9155
9903
  *
9156
9904
  * @param {Vectros.DeleteSchemaRequest} request
9157
9905
  * @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -9278,7 +10026,7 @@ var ScriptsClient = class {
9278
10026
  this._options = normalizeClientOptionsWithAuth(options);
9279
10027
  }
9280
10028
  /**
9281
- * Runs a script you previously pushed to `POST /v1/scripts`, under your own credential, and returns what it returned. Every write the script makes is buffered and committed as ONE transaction after the script finishes: either all of them land or none do, and the response is sent only after they have committed — so everything in `result` is committed state or the script's own computation over it. On any failure the body is the standard error envelope and nothing the script staged is committed: its rows are written only when the transaction commits, and a document body or a large payload is DECIDED at that point and WRITTEN to storage only after the commit, so an aborted execution leaves nothing behind. The one residual sits after a successful commit, outside this response: if storing a body fails then, the row exists and the body does not until the platform's repair lands — so a `200` guarantees the rows, and a document's text should be read before it is relied on.
10029
+ * Runs a script you previously pushed to `POST /v1/scripts`, under your own credential, and returns what it returned. Every write the script makes is buffered and committed as ONE transaction after the script finishes: either all of them land or none do, and the response is sent only after they have committed — so everything in `result` is committed state or the script's own computation over it. On any failure the body is the standard error envelope and nothing the script staged is committed: its rows are written only when the transaction commits, and a document body or a large payload is DECIDED at that point and WRITTEN to storage only after the commit, so an aborted execution leaves nothing behind. The one residual sits after a successful commit, outside this response: if storing a body fails then, the row exists and the body may not — so a `200` guarantees the rows, and a document's text should be read before it is relied on.
9282
10030
  *
9283
10031
  * **Permission.** Requires the `scripts:x` scope — the permission to *execute* — separate from the `scripts:c` permission to push scripts. Bare `scripts:x` grants every script in the context; `scripts:x:<name>` grants exactly that script name, every version of it. Execution discloses no source, so `scripts:r` is not needed. Inside the script, every read and write is enforced by your credential's data scopes exactly as the equivalent REST call would be — `scripts:x` alone can read and write nothing.
9284
10032
  *
@@ -9634,7 +10382,7 @@ var ScriptsClient = class {
9634
10382
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "PUT", "/v1/scripts/{id}");
9635
10383
  }
9636
10384
  /**
9637
- * Permanently deletes one script version by ID. Deleting one version does not affect any other version of the same name. Requires the `scripts:d` scope. Refused with 409 if a live trigger rule still references this version — either directly (a pinned `scriptRef`), or via `"latest"` when this IS the newest version of its name. Delete or re-point those rules first.
10385
+ * Permanently deletes one script version by ID. Deleting one version does not affect any other version of the same name. Requires the `scripts:d` scope. Refused with 409 if a live trigger rule still references this version — either directly (a pinned `scriptRef`), or via `"latest"` when this IS the newest version of its name. Delete or re-point those rules first. Also refused with a retryable 409, deleting nothing, when it cannot be told yet whether this is the newest version (for example just after several of this name's newest versions were deleted, or while its first version is gone and the listing has not caught up) and a `"latest"` rule depends on the script: try again shortly.
9638
10386
  *
9639
10387
  * @param {Vectros.DeleteScriptRequest} request
9640
10388
  * @param {ScriptsClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -9892,21 +10640,13 @@ var TriggersClient = class {
9892
10640
  *
9893
10641
  * @throws {@link Vectros.BadRequestError}
9894
10642
  * @throws {@link Vectros.ForbiddenError}
10643
+ * @throws {@link Vectros.NotFoundError}
10644
+ * @throws {@link Vectros.ConflictError}
9895
10645
  * @throws {@link Vectros.TooManyRequestsError}
9896
10646
  *
9897
10647
  * @example
9898
10648
  * await client.triggers.createTrigger({
9899
- * body: {
9900
- * name: "on-intake-create",
9901
- * firingSource: {
9902
- * schemaId: "sch_9f8e7d6c",
9903
- * event: "CREATE"
9904
- * },
9905
- * scriptRef: {
9906
- * name: "notify-assignee",
9907
- * version: "3"
9908
- * }
9909
- * }
10649
+ * body: {}
9910
10650
  * })
9911
10651
  */
9912
10652
  createTrigger(request, requestOptions) {
@@ -9949,6 +10689,10 @@ var TriggersClient = class {
9949
10689
  throw new BadRequestError(_response.error.body, _response.rawResponse);
9950
10690
  case 403:
9951
10691
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
10692
+ case 404:
10693
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
10694
+ case 409:
10695
+ throw new ConflictError(_response.error.body, _response.rawResponse);
9952
10696
  case 429:
9953
10697
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
9954
10698
  default:
@@ -10025,22 +10769,13 @@ var TriggersClient = class {
10025
10769
  * @throws {@link Vectros.BadRequestError}
10026
10770
  * @throws {@link Vectros.ForbiddenError}
10027
10771
  * @throws {@link Vectros.NotFoundError}
10772
+ * @throws {@link Vectros.ConflictError}
10028
10773
  * @throws {@link Vectros.TooManyRequestsError}
10029
10774
  *
10030
10775
  * @example
10031
10776
  * await client.triggers.updateTrigger({
10032
10777
  * id: "id",
10033
- * body: {
10034
- * name: "on-intake-create",
10035
- * firingSource: {
10036
- * schemaId: "sch_9f8e7d6c",
10037
- * event: "CREATE"
10038
- * },
10039
- * scriptRef: {
10040
- * name: "notify-assignee",
10041
- * version: "3"
10042
- * }
10043
- * }
10778
+ * body: {}
10044
10779
  * })
10045
10780
  */
10046
10781
  updateTrigger(request, requestOptions) {
@@ -10082,6 +10817,8 @@ var TriggersClient = class {
10082
10817
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
10083
10818
  case 404:
10084
10819
  throw new NotFoundError(_response.error.body, _response.rawResponse);
10820
+ case 409:
10821
+ throw new ConflictError(_response.error.body, _response.rawResponse);
10085
10822
  case 429:
10086
10823
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
10087
10824
  default:
@@ -10101,6 +10838,7 @@ var TriggersClient = class {
10101
10838
  * @param {TriggersClient.RequestOptions} requestOptions - Request-specific configuration.
10102
10839
  *
10103
10840
  * @throws {@link Vectros.NotFoundError}
10841
+ * @throws {@link Vectros.ConflictError}
10104
10842
  * @throws {@link Vectros.TooManyRequestsError}
10105
10843
  *
10106
10844
  * @example
@@ -10140,6 +10878,8 @@ var TriggersClient = class {
10140
10878
  switch (_response.error.statusCode) {
10141
10879
  case 404:
10142
10880
  throw new NotFoundError(_response.error.body, _response.rawResponse);
10881
+ case 409:
10882
+ throw new ConflictError(_response.error.body, _response.rawResponse);
10143
10883
  case 429:
10144
10884
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
10145
10885
  default:
@@ -10160,6 +10900,9 @@ var VectrosClient = class {
10160
10900
  get auth() {
10161
10901
  return this._auth ?? (this._auth = new AuthClient(this._options));
10162
10902
  }
10903
+ get agents() {
10904
+ return this._agents ?? (this._agents = new AgentsClient(this._options));
10905
+ }
10163
10906
  get documents() {
10164
10907
  return this._documents ?? (this._documents = new DocumentsClient(this._options));
10165
10908
  }
@@ -10230,7 +10973,7 @@ import {
10230
10973
  ListToolsRequestSchema,
10231
10974
  ReadResourceRequestSchema
10232
10975
  } from "@modelcontextprotocol/sdk/types.js";
10233
- import { z as z25 } from "zod";
10976
+ import { z as z28 } from "zod";
10234
10977
 
10235
10978
  // src/auth.ts
10236
10979
  var KEY_RE = /^(sk|ssk|st)_(live|test)_/;
@@ -10274,8 +11017,8 @@ function warnOnSuboptimalKey(key, log) {
10274
11017
 
10275
11018
  // src/build-info.ts
10276
11019
  var BUILD_INFO = {
10277
- mcpServer: true ? "0.18.1" : "dev",
10278
- sdk: true ? "0.47.0" : "dev"
11020
+ mcpServer: true ? "0.19.0" : "dev",
11021
+ sdk: true ? "0.49.0" : "dev"
10279
11022
  };
10280
11023
  function formatBuildInfo() {
10281
11024
  return `vectros-mcp-server ${BUILD_INFO.mcpServer} (sdk ${BUILD_INFO.sdk})`;
@@ -10534,6 +11277,11 @@ ${detail}${trailer}`
10534
11277
  };
10535
11278
  }
10536
11279
 
11280
+ // src/tools/limits.ts
11281
+ var MAX_OWNERSHIP_SCOPES = 2;
11282
+ var MAX_SCOPE_FILTERS = 16;
11283
+ var MAX_CONTENT_TYPES = 2;
11284
+
10537
11285
  // src/tools/hybrid_search.ts
10538
11286
  var MCP_DEFAULT_LIMIT = 3;
10539
11287
  var MCP_MAX_LIMIT = 50;
@@ -10576,11 +11324,11 @@ var inputSchema = {
10576
11324
  folderId: z.string().optional().describe("Scope to content in this EXACT folder (Vectros folder id)."),
10577
11325
  rootFolderId: z.string().optional().describe("Scope to content under this folder AND all its descendants (subtree-root folder id)."),
10578
11326
  // Content narrowing.
10579
- contentTypes: z.array(z.enum(["documents", "records"])).optional().describe('Narrow to content types. ["documents"] or ["records"]; omit for unified (both).'),
11327
+ contentTypes: z.array(z.enum(["documents", "records"])).max(MAX_CONTENT_TYPES, `contentTypes accepts at most ${MAX_CONTENT_TYPES} entries`).optional().describe('Narrow to content types. ["documents"] or ["records"]; omit for unified (both).'),
10580
11328
  typeName: z.string().optional().describe(
10581
11329
  'Restrict hits to this schema type (e.g. "patient", "runbook"). Applies to BOTH documents and records \u2014 combine with contentTypes to scope within one content type. Untyped content never matches.'
10582
11330
  ),
10583
- filters: z.record(z.unknown()).optional().describe(
11331
+ filters: z.record(z.string(), z.unknown()).optional().describe(
10584
11332
  'Field-level metadata filters (AND-combined). Value = scalar (equality), array (OR-set), or operator map: $eq/$ne/$gt/$gte/$lt/$lte (scalar) or $in/$nin (array). e.g. {"status":"open"} or {"price":{"$gte":100,"$lte":500}}.'
10585
11333
  ),
10586
11334
  // Ownership.
@@ -10588,7 +11336,7 @@ var inputSchema = {
10588
11336
  scope: z.string().optional().describe(
10589
11337
  'Restrict to content carrying this scope value, in `namespace:value` form (e.g. "org:<uuid>", "client:<uuid>", "group:eng-team"). `org` and `client` are reserved namespace names, registered like any other; others are namespaces you registered yourself. Mutually exclusive with `scopeFilters` \u2014 use this for ONE dimension.'
10590
11338
  ),
10591
- scopeFilters: z.array(z.string()).min(1, "scopeFilters must name at least one dimension when supplied").optional().describe(
11339
+ scopeFilters: z.array(z.string()).min(1, "scopeFilters must name at least one dimension when supplied").max(MAX_SCOPE_FILTERS, `scopeFilters accepts at most ${MAX_SCOPE_FILTERS} entries`).optional().describe(
10592
11340
  'Restrict to content matching ALL of these scope values \u2014 one per namespace \u2014 for a credential whose access spans more than one ownership dimension. e.g. ["org:<uuid>", "client:<uuid>"] narrows to one specific client WITHIN one specific org, which `scope` alone cannot express. Same `namespace:value` form as `scope`; naming the same namespace twice is rejected. Mutually exclusive with `scope` \u2014 use `scope` for a single dimension.'
10593
11341
  ),
10594
11342
  // Date window.
@@ -11109,7 +11857,7 @@ var inputSchema5 = {
11109
11857
  status: z5.string().optional().describe("Record lifecycle status. Defaults to ACTIVE server-side."),
11110
11858
  folderId: z5.string().optional().describe("Group this record into a folder."),
11111
11859
  userId: z5.string().optional().describe("Owning user id."),
11112
- scopes: z5.array(z5.string()).optional().describe(
11860
+ scopes: z5.array(z5.string()).max(MAX_OWNERSHIP_SCOPES, `scopes accepts at most ${MAX_OWNERSHIP_SCOPES} entries`).optional().describe(
11113
11861
  'Scope ownership as `namespace:value` entries, at most 2 (e.g. ["org:<uuid>", "group:eng-team"]). `org` and `client` are reserved namespace names, registered like any other; others are namespaces you registered yourself. This is the record\'s COMPLETE scope declaration, and each entry must fall inside the `data_scope` of a single clause of your credential that also grants this write \u2014 your identity supplies the DEFAULT when you state none, it does not limit which value you may state. An empty array `[]` creates a PRIVATE record owned by the calling user alone. Omit to stamp the credential\'s full identity \u2014 the default.'
11114
11862
  )
11115
11863
  };
@@ -11167,7 +11915,7 @@ var itemSchema = z6.strictObject({
11167
11915
  status: z6.string().optional().describe("Record lifecycle status. Defaults to ACTIVE server-side."),
11168
11916
  folderId: z6.string().optional().describe("Group this record into a folder."),
11169
11917
  userId: z6.string().optional().describe("Owning user id."),
11170
- scopes: z6.array(z6.string()).optional().describe(
11918
+ scopes: z6.array(z6.string()).max(MAX_OWNERSHIP_SCOPES, `scopes accepts at most ${MAX_OWNERSHIP_SCOPES} entries`).optional().describe(
11171
11919
  "Scope ownership as `namespace:value` entries, at most 2 namespaces. When supplied this is the record's COMPLETE scope declaration, and each entry must fall inside the `data_scope` of a single clause of your credential that also grants this write \u2014 your identity supplies the DEFAULT when you state none, it does not limit which value you may state. `[]` creates a PRIVATE record owned by the calling user alone. Omit to inherit the credential's full identity."
11172
11920
  )
11173
11921
  });
@@ -11254,7 +12002,7 @@ var inputSchema7 = {
11254
12002
  ),
11255
12003
  status: z7.string().optional().describe("Set the record lifecycle status (e.g. ARCHIVED) \u2014 archive/workflow without physical deletion."),
11256
12004
  expectedVersion: z7.number().int().optional().describe(
11257
- "Optimistic concurrency: the version you last read. If the record changed since, the update is refused as a conflict (re-read and retry). Omit for last-write-wins."
12005
+ "Optimistic concurrency: the version you last read. If the record changed since, the update is refused as a conflict (re-read and retry). Omit it to update whatever version is current: an update that meets another change to the same record at the same moment is still refused as a conflict."
11258
12006
  )
11259
12007
  };
11260
12008
  var recordUpdate = ({ client, log }) => ({
@@ -11324,7 +12072,7 @@ import { z as z10 } from "zod";
11324
12072
  // src/tools/provider-alias.ts
11325
12073
  import { z as z9 } from "zod";
11326
12074
  var providerAliasInput = z9.string().min(1, "providerAlias must be non-empty when supplied").optional().describe(
11327
- "Route THIS call through your own model provider instead of the platform-hosted default, by the alias of a provider config your account has activated. It works only after your account has set up that provider and signed the platform's risk-acceptance waiver; without both, the platform refuses the call with a 403, which is returned to you as written. If your account has accepted the Business Associate Agreement with Vectros in the developer portal, an account owner must also have attested that provider config in the developer portal (Model Providers); until then the platform refuses the call with a 403 that says it needs a BAA-holder attestation. A call served by your own provider leaves the Vectros perimeter. Omit it (the default) to use the platform-hosted path. When set, `model` names the model on your provider's own id space, and falls back to that provider config's default model when omitted."
12075
+ "Route THIS call through your own model provider instead of the platform-hosted default, by the alias of a provider config your account has activated. It works only after your account has set up that provider and signed the platform's risk-acceptance waiver; without both, the platform refuses the call with a 403, which is returned to you as written. When the waiver is the cause, the 403 carries an `errorCode` that says which case it is: `WAIVER_NOT_SIGNED` (the waiver has not been signed), `WAIVER_TEXT_CHANGED` (Vectros now requires a newer version of the waiver than the one in force for your account), or `WAIVER_REVOKED` (an owner revoked it). An account owner resolves each in the developer portal (Model Providers); retrying the call does not help. If your account has accepted the Business Associate Agreement with Vectros in the developer portal, an account owner must also have attested that provider config in the developer portal (Model Providers); until then the platform refuses the call with a 403 that says it needs a BAA-holder attestation. A call served by your own provider leaves the Vectros perimeter. Omit it (the default) to use the platform-hosted path. When set, `model` names the model on your provider's own id space, and falls back to that provider config's default model when omitted."
11328
12076
  );
11329
12077
 
11330
12078
  // src/tools/rag_ask.ts
@@ -11351,14 +12099,14 @@ var inputSchema9 = {
11351
12099
  scope: z10.string().optional().describe(
11352
12100
  'Restrict retrieval to content carrying this scope value, in `namespace:value` form (e.g. "org:<uuid>", "client:<uuid>", "group:eng-team"). `org` and `client` are reserved namespace names, registered like any other; others are namespaces you registered yourself. Mutually exclusive with `scopeFilters` \u2014 use this for ONE dimension.'
11353
12101
  ),
11354
- scopeFilters: z10.array(z10.string()).min(1, "scopeFilters must name at least one dimension when supplied").optional().describe(
12102
+ scopeFilters: z10.array(z10.string()).min(1, "scopeFilters must name at least one dimension when supplied").max(MAX_SCOPE_FILTERS, `scopeFilters accepts at most ${MAX_SCOPE_FILTERS} entries`).optional().describe(
11355
12103
  'Restrict retrieval to content matching ALL of these scope values \u2014 one per namespace \u2014 for a credential whose access spans more than one ownership dimension. e.g. ["org:<uuid>", "client:<uuid>"] grounds the answer on one specific client WITHIN one specific org, which `scope` alone cannot express. Naming the same namespace twice is rejected. Mutually exclusive with `scope`.'
11356
12104
  ),
11357
12105
  folderId: z10.string().optional().describe("Restrict retrieval to this exact folder."),
11358
12106
  rootFolderId: z10.string().optional().describe("Restrict retrieval to this folder and all its descendants."),
11359
12107
  typeName: z10.string().optional().describe("Restrict record retrieval to this schema type."),
11360
- contentTypes: z10.array(z10.enum(["documents", "records"])).optional().describe('Narrow retrieval to content types. ["documents"] or ["records"]; omit for both.'),
11361
- filters: z10.record(z10.unknown()).optional().describe(
12108
+ contentTypes: z10.array(z10.enum(["documents", "records"])).max(MAX_CONTENT_TYPES, `contentTypes accepts at most ${MAX_CONTENT_TYPES} entries`).optional().describe('Narrow retrieval to content types. ["documents"] or ["records"]; omit for both.'),
12109
+ filters: z10.record(z10.string(), z10.unknown()).optional().describe(
11362
12110
  'Field-level metadata filters (AND-combined). Value = scalar (equality), array (OR-set), or operator map ($eq/$ne/$gt/$gte/$lt/$lte, $in/$nin). e.g. {"status":"open"}.'
11363
12111
  ),
11364
12112
  createdAfter: z10.string().optional().describe(
@@ -11633,7 +12381,7 @@ function isNotAvailable(err) {
11633
12381
  var documentGet = ({ client, log }) => ({
11634
12382
  name: "document_get",
11635
12383
  title: "Get document metadata (and optionally text)",
11636
- description: "Fetch metadata for a single document \u2014 select it by its Vectros `documentId` OR by your own `externalId` + `type` (resolved for you). Pass `includeText: true` to also fetch the text body (capped at ~8K tokens; `truncated: true` flag if cut). Text is available for every text-ingested document and for file-ingested documents unless they were uploaded with `storeText: false` (extracted text discarded after indexing) \u2014 then `textAvailable: false` is set; the original file is still retrievable via `includeDownloadUrl`. Pass `includeDownloadUrl: true` to also get a short-lived presigned `downloadUrl` for the original file (file-backed documents only). Returns the full document metadata, including its lifecycle `status` (ACTIVE, or ARCHIVED when soft-retracted from search \u2014 restorable via document_update) and its processing `indexStatus`. When `indexStatus` is FAILED the response also carries `indexFailure` with a machine-readable `code` telling you whether the content is still findable \u2014 e.g. TEXT_INDEX_FAILED / VECTOR_LIMIT_EXCEEDED (one leg still serves it) vs INDEXING_FAILED (not findable by search at all). Branch on `code`, not on the message.",
12384
+ description: "Fetch metadata for a single document \u2014 select it by its Vectros `documentId` OR by your own `externalId` + `type` (resolved for you). Pass `includeText: true` to also fetch the text body (capped at ~8K tokens; `truncated: true` flag if cut). Text is available for every text-ingested document and for file-ingested documents unless they were uploaded with `storeText: false` (extracted text discarded after indexing) or no text could be extracted from the file (`extraction.outcome` other than OK/TRUNCATED, e.g. an image or a scanned page) \u2014 then `textAvailable: false` is set; the original file is still retrievable via `includeDownloadUrl`. Pass `includeDownloadUrl: true` to also get a short-lived presigned `downloadUrl` for the original file (file-backed documents only). Returns the full document metadata, including its lifecycle `status` (ACTIVE, or ARCHIVED when soft-retracted from search \u2014 restorable via document_update) and its processing `indexStatus`. When `indexStatus` is FAILED the response also carries `indexFailure` with a machine-readable `code` telling you whether the content is still findable \u2014 e.g. TEXT_INDEX_FAILED / VECTOR_LIMIT_EXCEEDED (one leg still serves it) vs INDEXING_FAILED (not findable by search at all). Branch on `code`, not on the message.",
11637
12385
  inputSchema: inputSchema12,
11638
12386
  // A pure read — never creates, modifies, or deletes anything server-side.
11639
12387
  annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },
@@ -11659,7 +12407,7 @@ var documentGet = ({ client, log }) => ({
11659
12407
  if (isNotAvailable(textErr)) {
11660
12408
  log.debug(
11661
12409
  { tool: "document_get", id },
11662
- "document_get text unavailable (not retained \u2014 storeText:false upload)"
12410
+ "document_get text unavailable (not retained, or no text could be extracted from the file)"
11663
12411
  );
11664
12412
  extra = { ...extra, textAvailable: false };
11665
12413
  } else {
@@ -11712,10 +12460,12 @@ var inputSchema13 = {
11712
12460
  to: z14.string().optional().describe("Lookup mode (range): inclusive upper bound; requires `from`."),
11713
12461
  prefix: z14.string().optional().describe("Lookup mode (prefix): match values starting with this. Range-enabled string fields only."),
11714
12462
  order: z14.enum(["asc", "desc"]).optional().describe(
11715
- "Lookup mode: sort direction by the looked-up field. `asc` (default) or `desc` \u2014 use `desc` with a range/prefix lookup to get the most-recent / highest values first (e.g. latest-N). Ignored in list mode."
12463
+ "Lookup mode: sort direction by the looked-up field. `asc` (default) or `desc` \u2014 use `desc` with a range/prefix lookup to get the most-recent / highest values first (e.g. latest-N). Refused without `field`."
11716
12464
  ),
11717
- type: z14.string().optional().describe("Lookup mode: the document type (the bound schema's type). Required with `field`."),
11718
- // List-mode args:
12465
+ type: z14.string().min(1, "type must be non-empty: omit it to list every type").optional().describe(
12466
+ "The document type (the bound schema's type). Required with `field` (lookup mode); in list mode it narrows the list to documents of this type. The list filter applies page by page: a page can hold fewer documents than `limit`, or none, while `nextCursor` is set, so keep paging until `nextCursor` is null before concluding there are none. For a large collection, hybrid_search with `typeName` finds documents of one type directly."
12467
+ ),
12468
+ // List-mode args (`type` above applies to both modes):
11719
12469
  folderId: z14.string().optional().describe("List mode: only documents in this folder (Vectros folder id)."),
11720
12470
  userId: z14.string().optional().describe("List mode: scope to documents owned by this user."),
11721
12471
  scope: z14.string().optional().describe(
@@ -11729,7 +12479,7 @@ var inputSchema13 = {
11729
12479
  var documentQuery = ({ client, log }) => ({
11730
12480
  name: "document_query",
11731
12481
  title: "Document query (list or lookup)",
11732
- description: "Query document metadata. Two modes:\n \u2022 Lookup on a lookup-indexed field: pass `type` and `field` plus exactly one of `value` (exact), `from`+`to` (range), or `prefix`. Works on sensitive fields (equality only there); range/prefix need a range-enabled field.\n \u2022 List: omit `field`; optionally filter by `folderId`/`userId`/`scope` (`namespace:value`).\nReturns a `{ data, nextCursor }` page: `data` holds up to `limit` documents (default 3, max 100 \u2014 raise it in one call when you can accept the payload), and a non-null `nextCursor` means more remain \u2014 pass it back as `startFrom` to page. Mode is auto-detected. Use document_get for the full text/download URL of one document.",
12482
+ description: "Query document metadata. Two modes:\n \u2022 Lookup on a lookup-indexed field: pass `type` and `field` plus exactly one of `value` (exact), `from`+`to` (range), or `prefix`. Works on sensitive fields (equality only there); range/prefix need a range-enabled field.\n \u2022 List: omit `field`; optionally filter by `type`/`folderId`/`userId`/`scope` (`namespace:value`). The `type` filter is applied page by page, so a page can be short or empty while `nextCursor` is set: keep paging before concluding there are none.\nReturns a `{ data, nextCursor }` page: `data` holds up to `limit` documents (default 3, max 100 \u2014 raise it in one call when you can accept the payload), and a non-null `nextCursor` means more remain \u2014 pass it back as `startFrom` to page. Mode is auto-detected. Use document_get for the full text/download URL of one document.",
11733
12483
  inputSchema: inputSchema13,
11734
12484
  // A pure read — never creates, modifies, or deletes anything server-side.
11735
12485
  annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },
@@ -11788,7 +12538,19 @@ var documentQuery = ({ client, log }) => ({
11788
12538
  "document_query lookup ok"
11789
12539
  );
11790
12540
  } else {
12541
+ const strayLookupArgs = ["value", "from", "to", "prefix", "order"].filter(
12542
+ (k) => args[k] !== void 0
12543
+ );
12544
+ if (strayLookupArgs.length > 0) {
12545
+ return toolError(
12546
+ "document_query",
12547
+ new Error(
12548
+ `Lookup arguments need 'field' (and 'type'): ${strayLookupArgs.map((k) => `'${k}'`).join(", ")}. Without 'field' the call lists documents: filter the list with 'type', 'folderId', 'userId' or 'scope'.`
12549
+ )
12550
+ );
12551
+ }
11791
12552
  page = await client.documents.listDocuments({
12553
+ type,
11792
12554
  folderId: args.folderId,
11793
12555
  userId: args.userId,
11794
12556
  scope: args.scope,
@@ -11796,7 +12558,7 @@ var documentQuery = ({ client, log }) => ({
11796
12558
  limit
11797
12559
  });
11798
12560
  log.debug(
11799
- { tool: "document_query", mode: "list", limit, returned: pageItems(page).length },
12561
+ { tool: "document_query", mode: "list", type, limit, returned: pageItems(page).length },
11800
12562
  "document_query list ok"
11801
12563
  );
11802
12564
  }
@@ -11831,11 +12593,11 @@ var inputSchema14 = {
11831
12593
  "Lifecycle status. `ARCHIVED` soft-retracts the document \u2014 it is pulled from search and recall but kept and recoverable; set it back to `ACTIVE` to re-index and restore it. The way to retire superseded content when the credential has no delete authority. Omit to leave unchanged."
11832
12594
  ),
11833
12595
  userId: z15.string().optional().describe("Reassign the owning user (Vectros UUID)."),
11834
- scopes: z15.array(z15.string()).optional().describe(
12596
+ scopes: z15.array(z15.string()).max(MAX_OWNERSHIP_SCOPES, `scopes accepts at most ${MAX_OWNERSHIP_SCOPES} entries`).optional().describe(
11835
12597
  'Reassign scope ownership as `namespace:value` entries, at most 2 (e.g. ["org:<uuid>", "group:eng-team"]) \u2014 the COMPLETE new parent set. `org`/`client` are reserved namespace names, registered like any other. Omit to leave ownership unchanged; `[]` clears it (private to the owning user).'
11836
12598
  ),
11837
12599
  expectedVersion: z15.number().int().optional().describe(
11838
- "Optimistic concurrency: the version you last read. If the document changed since, the update is refused as a conflict (re-read and retry). Omit for last-write-wins."
12600
+ "Optimistic concurrency: the version you last read. If the document changed since, the update is refused as a conflict (re-read and retry). Omit it to update whatever version is current: an update that meets another change to the same document at the same moment is still refused as a conflict."
11839
12601
  )
11840
12602
  };
11841
12603
  var documentUpdate = ({ client, log }) => ({
@@ -11975,7 +12737,7 @@ var inputSchema17 = {
11975
12737
  "Optional stable slug (sibling-unique; idempotency key). Lowercase letters/digits/hyphens. SUPPLY THIS to make a retry safe \u2014 if omitted, a derived slug is only ever a freshly-proved-free one, so a redelivered call creates a new sibling folder every time rather than matching the first."
11976
12738
  ),
11977
12739
  userId: z18.string().optional().describe("Owning user (Vectros UUID)."),
11978
- scopes: z18.array(z18.string()).optional().describe(
12740
+ scopes: z18.array(z18.string()).max(MAX_OWNERSHIP_SCOPES, `scopes accepts at most ${MAX_OWNERSHIP_SCOPES} entries`).optional().describe(
11979
12741
  'Scope ownership as `namespace:value` entries, at most 2 (e.g. ["org:<uuid>", "group:eng-team"]). `org` and `client` are reserved namespace names, registered like any other; others are namespaces you registered yourself. This is the folder\'s COMPLETE scope declaration and values must come from the credential\'s own identity. An empty array `[]` creates a PRIVATE folder owned by the calling user alone. Omit to stamp the credential\'s full identity \u2014 the default.'
11980
12742
  )
11981
12743
  };
@@ -11989,10 +12751,8 @@ var folderCreate = ({ client, log }) => ({
11989
12751
  // freshly-proved-free value, so the idempotency check running after that derivation can never
11990
12752
  // match on the default path. `slug` is optional, so this is annotated for the less-safe default —
11991
12753
  // the same standard applied to record_create/document_ingest/record_batch_write's identical
11992
- // optional-dedupe-key shape. (A prior version of this annotation claimed unconditional
11993
- // idempotency, reasoning that the derived slug made this tool "genuinely structurally different"
11994
- // from the optional-externalId tools — that reasoning was wrong: the derivation is unconditional,
11995
- // but it is unconditionally NON-colliding by construction, which is the opposite property.)
12754
+ // optional-dedupe-key shape. (The slug derivation being unconditional does not make the tool
12755
+ // idempotent: it is unconditionally NON-colliding by construction, which is the opposite property.)
11996
12756
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },
11997
12757
  handler: async (args) => {
11998
12758
  try {
@@ -12023,11 +12783,11 @@ var inputSchema18 = {
12023
12783
  name: z19.string().optional().describe("New folder name. Omit to keep the current name."),
12024
12784
  description: z19.string().optional().describe("New description. Omit to leave unchanged."),
12025
12785
  userId: z19.string().optional().describe("Reassign the owning user (Vectros UUID)."),
12026
- scopes: z19.array(z19.string()).optional().describe(
12786
+ scopes: z19.array(z19.string()).max(MAX_OWNERSHIP_SCOPES, `scopes accepts at most ${MAX_OWNERSHIP_SCOPES} entries`).optional().describe(
12027
12787
  'Reassign scope ownership as `namespace:value` entries, at most 2 (e.g. ["org:<uuid>", "group:eng-team"]) \u2014 the COMPLETE new parent set. `org`/`client` are reserved namespace names, registered like any other. Omit to leave ownership unchanged; `[]` clears it (private to the owning user).'
12028
12788
  ),
12029
12789
  expectedVersion: z19.number().int().optional().describe(
12030
- "Optimistic concurrency: the version you last read. If the folder changed since, the update is refused as a conflict (re-read and retry). Omit for last-write-wins."
12790
+ "Optimistic concurrency: the version you last read. If the folder changed since, the update is refused as a conflict (re-read and retry). Omit it to update whatever version is current: an update that meets another change to the same folder at the same moment is still refused as a conflict."
12031
12791
  )
12032
12792
  };
12033
12793
  var folderUpdate = ({ client, log }) => ({
@@ -12072,7 +12832,7 @@ var inputSchema19 = {
12072
12832
  var folderDelete = ({ client, log }) => ({
12073
12833
  name: "folder_delete",
12074
12834
  title: "Delete a folder",
12075
- description: 'Permanently delete a folder by id. The folder must be EMPTY first \u2014 it must contain no documents, no records, and no sub-folders \u2014 and a non-empty folder is refused, which is the most common way this call fails. Use record_query with this folderId, and document_query, to see what is in it. Clearing it differs by content type: a document can be moved out (document_update with a different folderId) or deleted. A RECORD can also be re-filed into another folder \u2014 the API supports it \u2014 but THIS SERVER does not expose that yet: record_update has no folderId argument, so from here your only option is record_delete (needs records:d). Do NOT read that as "the record cannot be moved" and delete the record on that basis: if the record should be kept, tell the user to move it with the Vectros API/SDK directly rather than deleting it here. A sub-folder cannot be re-parented at all, so nested folders have to be emptied and deleted innermost-first. Note the emptiness check counts everything in the folder, INCLUDING items your credential cannot read \u2014 so a refusal you cannot account for from what you can list is expected behaviour, not a bug, and retrying will not clear it. Requires the key to allow folders:d \u2014 a key without it gets a permission error. Protected folders (e.g. a context root) cannot be deleted at all, however empty.',
12835
+ description: 'Permanently delete a folder by id. The folder must be EMPTY first \u2014 it must contain no documents, no records, and no sub-folders \u2014 and a non-empty folder is refused, which is the most common way this call fails. Use record_query with this folderId, and document_query, to see what is in it. Clearing it differs by content type: a document can be moved out (document_update with a different folderId) or deleted. A RECORD can also be re-filed into another folder \u2014 the API supports it \u2014 but THIS SERVER does not expose that: record_update has no folderId argument, so from here your only option is record_delete (needs records:d). Do NOT read that as "the record cannot be moved" and delete the record on that basis: if the record should be kept, tell the user to move it with the Vectros API/SDK directly rather than deleting it here. A sub-folder cannot be re-parented at all, so nested folders have to be emptied and deleted innermost-first. Note the emptiness check counts everything in the folder, INCLUDING items your credential cannot read \u2014 so a refusal you cannot account for from what you can list is expected behaviour, not a bug, and retrying will not clear it. Requires the key to allow folders:d \u2014 a key without it gets a permission error. Protected folders (e.g. a context root) cannot be deleted at all, however empty.',
12076
12836
  inputSchema: inputSchema19,
12077
12837
  // Deletes. Idempotent in the standard REST sense: the end state ("this id no longer
12078
12838
  // resolves") is the same whether this is the first delete or a repeat of one.
@@ -12098,7 +12858,7 @@ var inputSchema20 = {
12098
12858
  var currentIdentity = ({ log, apiKey, environment }) => ({
12099
12859
  name: "current_identity",
12100
12860
  title: "Current identity (tenant + principal scope)",
12101
- description: "Describe the credential the MCP server is operating under. Returns tenantId, environment (staging|production), principalType (root_key|scoped_key|token), principalKeyId, principalLabel, and (for scoped credentials) allowedActions plus dataScope \u2014 the credential's verb+ownership reach as { userId, scopes[] }, where each scope is a `namespace:value` string (e.g. \"org:<uuid>\"). Note: this does not yet include granted_capabilities (member-lifecycle / forensic-read / context-directory-read / delegate-mint, as of API 0.40.0, joined by delegate-principal-stamp in 0.42.0) \u2014 a separate reach dimension a scope clause can carry that /v1/ping does not report yet, so allowedActions+dataScope may understate a credential's true reach. Also reports mcpServerVersion (this server's own package version) and sdkVersion (the bundled @vectros-ai/sdk version) so a caller can tell what build it's talking to. Use this when the user asks 'what can you do here?', 'what tenant am I in?', or 'what version is this?'. Calls GET /v1/ping under the hood.",
12861
+ description: "Describe the credential the MCP server is operating under. Returns tenantId, environment (staging|production), principalType (root_key|scoped_key|token), principalKeyId, principalLabel, and (for scoped credentials) allowedActions plus dataScope \u2014 the credential's verb+ownership reach as { userId, scopes[] }, where each scope is a `namespace:value` string (e.g. \"org:<uuid>\"). Note: this does not include granted_capabilities (member-lifecycle / forensic-read / context-directory-read / delegate-mint, as of API 0.40.0, joined by delegate-principal-stamp in 0.42.0 and trigger-control-plane-grant in 0.44.0) \u2014 a separate reach dimension a scope clause can carry that /v1/ping does not report, so allowedActions+dataScope may understate a credential's true reach. Also reports mcpServerVersion (this server's own package version) and sdkVersion (the bundled @vectros-ai/sdk version) so a caller can tell what build it's talking to. Use this when the user asks 'what can you do here?', 'what tenant am I in?', or 'what version is this?'. Calls GET /v1/ping under the hood.",
12102
12862
  inputSchema: inputSchema20,
12103
12863
  // A pure read (/v1/ping) — never creates, modifies, or deletes anything server-side.
12104
12864
  annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },
@@ -12225,14 +12985,14 @@ var inputSchema21 = {
12225
12985
  // Common (both modes):
12226
12986
  folderId: z21.string().optional().describe("Optional folder to ingest into. Default: tenant root."),
12227
12987
  userId: z21.string().optional().describe("Owning user ID. Optional."),
12228
- scopes: z21.array(z21.string()).optional().describe(
12988
+ scopes: z21.array(z21.string()).max(MAX_OWNERSHIP_SCOPES, `scopes accepts at most ${MAX_OWNERSHIP_SCOPES} entries`).optional().describe(
12229
12989
  "TEXT MODE ONLY. Scope ownership as `namespace:value` entries, at most 2 (e.g. [\"org:<uuid>\", \"group:eng-team\"]). `org` and `client` are reserved namespace names, registered like any other; others are namespaces you registered yourself. This is the document's COMPLETE scope declaration and values must come from the credential's own identity. An empty array `[]` creates a PRIVATE document owned by the calling user alone. Omit to stamp the credential's full identity \u2014 the default. Rejected with `filePath` (file uploads do not accept a scope declaration): a file-uploaded document is stamped with the credential's full identity."
12230
12990
  )
12231
12991
  };
12232
12992
  var documentIngest = ({ client, log, transport, ingestRoot }) => ({
12233
12993
  name: "document_ingest",
12234
12994
  title: "Ingest a new document (text body or file upload)",
12235
- description: "Create a new document in your Vectros tenant. Two modes:\n \u2022 Text mode: pass `text` (string body). Single-call. Use for crawled content, notes, generated text.\n \u2022 File mode: pass `filePath` (local path on the MCP server's host machine). STDIO-TRANSPORT ONLY \u2014 rejected on HTTP transport. MCP server reads the bytes, requests a presigned upload URL, and PUTs them. Returns when the upload is accepted (indexStatus: PENDING_INDEX); poll `document_get` until indexStatus is INDEXED. EXCEPTION \u2014 re-ingesting file mode against an externalId that already has a document (response `created:false`): the file body is replaced by ANY such re-ingest, whether or not `upsert` was set (`upsert` there only additionally applies `payload`/`title` to the matched document). The document keeps serving the OLD file's bytes until the new one is adopted, and indexStatus already reads INDEXED left over from that old file, so polling it returns immediately without waiting for the new content. Poll `document_get` and watch `fileItemId` instead \u2014 once it differs from the value it held before this call, the new file has been adopted. Re-request any download URL after that: one minted before adoption can stop working even within its stated `downloadExpires`.\nEither `text` or `filePath` must be present; both is an error. Idempotent by `externalId` (re-ingest returns the existing document, not a duplicate \u2014 requires documents:r in addition to documents:c, since being handed the existing document is a read of it; in FILE MODE a re-ingest against an existing externalId needs documents:u). TEXT MODE: without `upsert`, the existing document's content is genuinely unchanged. FILE MODE: as noted above, a re-ingest against an existing externalId always replaces the file body regardless of `upsert` \u2014 only the `payload`/`title` metadata overwrite is gated by it. To UPDATE an existing document instead \u2014 re-index an edited body \u2014 pass `upsert:true` with the same `externalId` (and the same `schemaId`); this is the re-sync primitive for keeping a knowledge base current. Pass `schemaId` + `payload` for a typed, lookup-queryable document (records parity). An `externalId` with no `schemaId` is refused (400) unless you also pass `confirmUntyped:true` to confirm that an untyped document is intended. indexMode defaults to HYBRID for untyped documents (omit to inherit a bound schema's default). storeText is a FILE-MODE knob (default true): false discards the uploaded file's extracted text after indexing (search + file download keep working; text retrieval and document_ask do not). Text-mode bodies are always retained, so storeText is not accepted with `text`.",
12995
+ description: "Create a new document in your Vectros tenant. Two modes:\n \u2022 Text mode: pass `text` (string body). Single-call. Use for crawled content, notes, generated text.\n \u2022 File mode: pass `filePath` (local path on the MCP server's host machine). STDIO-TRANSPORT ONLY \u2014 rejected on HTTP transport. MCP server reads the bytes, requests a presigned upload URL, and PUTs them. Returns when the upload is accepted (indexStatus: PENDING_INDEX); poll `document_get` until indexStatus is terminal: INDEXED, SKIPPED (no indexable text: `extraction.outcome` says why, e.g. NO_TEXT for an image or a scanned page), STORED (indexMode NONE) or FAILED. EXCEPTION \u2014 re-ingesting file mode against an externalId that already has a document (response `created:false`): the file body is replaced by ANY such re-ingest, whether or not `upsert` was set (`upsert` there only additionally applies `payload`/`title` to the matched document). The document keeps serving the OLD file's bytes until the new one is adopted, and indexStatus already reads INDEXED left over from that old file, so polling it returns immediately without waiting for the new content. Poll `document_get` and watch `fileItemId` instead \u2014 once it differs from the value it held before this call, the new file has been adopted. Re-request any download URL after that: one minted before adoption can stop working even within its stated `downloadExpires`.\nEither `text` or `filePath` must be present; both is an error. Idempotent by `externalId` (re-ingest returns the existing document, not a duplicate \u2014 requires documents:r in addition to documents:c, since being handed the existing document is a read of it; in FILE MODE a re-ingest against an existing externalId needs documents:u). TEXT MODE: without `upsert`, the existing document's content is genuinely unchanged. FILE MODE: as noted above, a re-ingest against an existing externalId always replaces the file body regardless of `upsert` \u2014 only the `payload`/`title` metadata overwrite is gated by it. To UPDATE an existing document instead \u2014 re-index an edited body \u2014 pass `upsert:true` with the same `externalId` (and the same `schemaId`); this is the re-sync primitive for keeping a knowledge base current. Pass `schemaId` + `payload` for a typed, lookup-queryable document (records parity). An `externalId` with no `schemaId` is refused (400) unless you also pass `confirmUntyped:true` to confirm that an untyped document is intended. indexMode defaults to HYBRID for untyped documents (omit to inherit a bound schema's default). storeText is a FILE-MODE knob (default true): false discards the uploaded file's extracted text after indexing (search + file download keep working; text retrieval and document_ask do not). Text-mode bodies are always retained, so storeText is not accepted with `text`.",
12236
12996
  inputSchema: inputSchema21,
12237
12997
  // Creates by default, idempotent ONLY when the caller supplies `externalId` (optional,
12238
12998
  // per the doc comment above) — re-ingest then returns the existing document rather than
@@ -12374,7 +13134,7 @@ var documentIngest = ({ client, log, transport, ingestRoot }) => ({
12374
13134
  "document_ingest file ok"
12375
13135
  );
12376
13136
  const uploadCreated = upload?.created;
12377
- const note = uploadCreated === false ? "File replaced: this re-ingest matched an existing externalId, which always replaces that document's file body (upsert or not \u2014 upsert only additionally applies payload/title to it). The next document_get call may already show indexStatus: INDEXED \u2014 that is left over from the PREVIOUS file, not confirmation the new one is ready, and the document keeps serving the old file's bytes until adoption completes. Poll document_get(id) and watch fileItemId instead: once it differs from the value it held before this call, the new file has been adopted. Any download URL already held for this document was minted for the old file and can stop working before its stated downloadExpires once adoption happens \u2014 request a fresh one after fileItemId changes." : "File uploaded; indexing is asynchronous. Poll document_get(id) until indexStatus is INDEXED.";
13137
+ const note = uploadCreated === false ? "File replaced: this re-ingest matched an existing externalId, which always replaces that document's file body (upsert or not \u2014 upsert only additionally applies payload/title to it). The next document_get call may already show indexStatus: INDEXED \u2014 that is left over from the PREVIOUS file, not confirmation the new one is ready, and the document keeps serving the old file's bytes until adoption completes. Poll document_get(id) and watch fileItemId instead: once it differs from the value it held before this call, the new file has been adopted. Any download URL already held for this document was minted for the old file and can stop working before its stated downloadExpires once adoption happens \u2014 request a fresh one after fileItemId changes." : "File uploaded; indexing is asynchronous. Poll document_get(id) until indexStatus is INDEXED, SKIPPED (no indexable text; see extraction.outcome), STORED or FAILED.";
12378
13138
  return {
12379
13139
  content: [
12380
13140
  {
@@ -12547,6 +13307,365 @@ var versionHistory = ({ client, log }) => ({
12547
13307
  });
12548
13308
  var version_history_default = versionHistory;
12549
13309
 
13310
+ // src/tools/agent_list.ts
13311
+ import { z as z24 } from "zod";
13312
+ var MCP_DEFAULT_LIMIT6 = 10;
13313
+ var MCP_MAX_LIMIT6 = 100;
13314
+ function toAgentSummary(agent) {
13315
+ return {
13316
+ id: agent.id,
13317
+ name: agent.name,
13318
+ description: agent.description,
13319
+ latestVersion: agent.latestVersion,
13320
+ status: agent.status
13321
+ };
13322
+ }
13323
+ var inputSchema24 = {
13324
+ includeRetired: z24.boolean().optional().describe("Also list retired and purged agents (neither can be run). Default false."),
13325
+ startFrom: z24.string().optional().describe("Pagination cursor: pass the `nextCursor` from the previous page to fetch the next."),
13326
+ limit: z24.number().int().min(1).max(MCP_MAX_LIMIT6).optional().describe(`Max agents per page. Default ${MCP_DEFAULT_LIMIT6}, max ${MCP_MAX_LIMIT6}.`)
13327
+ };
13328
+ var agentList = ({ client, log }) => ({
13329
+ name: "agent_list",
13330
+ title: "List agents",
13331
+ description: "List the stored agents you can run with agent_run, newest first. Each is returned as its `id`, `name`, `description`, `latestVersion` and `status`; only an `ACTIVE` agent can be run. Retired and purged agents are left out unless `includeRetired` is true. Returns a `{ data, nextCursor }` page: a non-null `nextCursor` means more remain, pass it back as `startFrom`. Needs the `runs:c` or `agents:r` scope; running a listed agent needs `runs:c`, so a credential with only `agents:r` can list agents but not run them.",
13332
+ inputSchema: inputSchema24,
13333
+ // A pure read: it lists definitions and changes nothing.
13334
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },
13335
+ handler: async (args) => {
13336
+ const limit = args.limit ?? MCP_DEFAULT_LIMIT6;
13337
+ try {
13338
+ const page = await client.agents.listAgents({
13339
+ includeRetired: args.includeRetired,
13340
+ startFrom: args.startFrom,
13341
+ limit
13342
+ });
13343
+ const data = (page.data ?? []).map(toAgentSummary);
13344
+ const nextCursor = page.nextCursor ?? null;
13345
+ log.debug({ tool: "agent_list", limit, returned: data.length }, "agent_list ok");
13346
+ return { content: [{ type: "text", text: JSON.stringify({ data, nextCursor }, null, 2) }] };
13347
+ } catch (err) {
13348
+ log.warn({ tool: "agent_list", err: String(err) }, "agent_list failed");
13349
+ return toolError("agent_list", err);
13350
+ }
13351
+ }
13352
+ });
13353
+ var agent_list_default = agentList;
13354
+
13355
+ // src/tools/agent_run.ts
13356
+ import { randomUUID } from "crypto";
13357
+ import { z as z25 } from "zod";
13358
+
13359
+ // src/run-stream.ts
13360
+ var TEXT_PROGRESS_CHARS = 256;
13361
+ var HEARTBEAT_MS = 15e3;
13362
+ var TERMINAL_STATUS = {
13363
+ "run.completed": "COMPLETED",
13364
+ "run.failed": "FAILED",
13365
+ "run.cancelled": "CANCELLED"
13366
+ };
13367
+ function str(v) {
13368
+ return typeof v === "string" && v.length > 0 ? v : void 0;
13369
+ }
13370
+ function num(v) {
13371
+ return typeof v === "number" && Number.isFinite(v) ? v : void 0;
13372
+ }
13373
+ async function consumeRunStream(stream, initialRunId, onProgress, heartbeatMs = HEARTBEAT_MS) {
13374
+ const result = {
13375
+ runId: initialRunId,
13376
+ terminal: false,
13377
+ status: "UNKNOWN",
13378
+ text: "",
13379
+ toolCalls: []
13380
+ };
13381
+ const blocks = [];
13382
+ let pending = "";
13383
+ let unsentChars = 0;
13384
+ const emit = async (message) => {
13385
+ if (!onProgress) return;
13386
+ try {
13387
+ await onProgress(message);
13388
+ } catch {
13389
+ }
13390
+ };
13391
+ let heartbeat;
13392
+ let lastEventAt = Date.now();
13393
+ if (onProgress) {
13394
+ heartbeat = setInterval(() => {
13395
+ if (Date.now() - lastEventAt >= heartbeatMs) {
13396
+ lastEventAt = Date.now();
13397
+ void emit("run still working");
13398
+ }
13399
+ }, Math.max(1, Math.floor(heartbeatMs / 3)));
13400
+ heartbeat.unref?.();
13401
+ }
13402
+ try {
13403
+ for await (const raw of stream) {
13404
+ lastEventAt = Date.now();
13405
+ if (!raw || typeof raw !== "object") continue;
13406
+ const ev = raw;
13407
+ result.runId ??= str(ev.runId);
13408
+ const type = typeof ev.type === "string" ? ev.type : "";
13409
+ switch (type) {
13410
+ case "run.started":
13411
+ result.agentId = str(ev.agentId) ?? result.agentId;
13412
+ result.agentVersion = num(ev.agentVersion) ?? result.agentVersion;
13413
+ await emit("run started");
13414
+ break;
13415
+ case "message.delta": {
13416
+ const piece = typeof ev.text === "string" ? ev.text : "";
13417
+ pending += piece;
13418
+ unsentChars += piece.length;
13419
+ if (unsentChars >= TEXT_PROGRESS_CHARS) {
13420
+ unsentChars = 0;
13421
+ await emit(`answer: ${blocks.join("\n\n").length + pending.length} characters so far`);
13422
+ }
13423
+ break;
13424
+ }
13425
+ case "message.completed": {
13426
+ const full = str(ev.text) ?? pending;
13427
+ if (full.length > 0) blocks.push(full);
13428
+ pending = "";
13429
+ unsentChars = 0;
13430
+ await emit("model call completed");
13431
+ break;
13432
+ }
13433
+ case "tool.completed": {
13434
+ const call = {
13435
+ tool: str(ev.tool),
13436
+ outcome: str(ev.outcome),
13437
+ code: str(ev.code)
13438
+ };
13439
+ result.toolCalls.push(call);
13440
+ await emit(`tool ${call.tool ?? "call"}: ${call.outcome ?? "ended"}`);
13441
+ break;
13442
+ }
13443
+ default:
13444
+ break;
13445
+ }
13446
+ if (ev.terminal === true || Object.hasOwn(TERMINAL_STATUS, type)) {
13447
+ result.terminal = true;
13448
+ result.status = str(ev.status) ?? TERMINAL_STATUS[type] ?? "ENDED";
13449
+ result.reason = str(ev.reason);
13450
+ result.errorCode = str(ev.errorCode);
13451
+ if (typeof ev.settled === "boolean" || ev.inferenceBalanceCentsChargedMilli !== void 0 || ev.inferenceBalanceCentsRefundedMilli !== void 0) {
13452
+ result.charged = {
13453
+ settled: typeof ev.settled === "boolean" ? ev.settled : void 0,
13454
+ inferenceBalanceCentsChargedMilli: num(ev.inferenceBalanceCentsChargedMilli),
13455
+ inferenceBalanceCentsRefundedMilli: num(ev.inferenceBalanceCentsRefundedMilli)
13456
+ };
13457
+ }
13458
+ break;
13459
+ }
13460
+ }
13461
+ } catch (err) {
13462
+ result.streamError = err instanceof Error ? err.message : String(err);
13463
+ } finally {
13464
+ if (heartbeat) clearInterval(heartbeat);
13465
+ }
13466
+ if (pending.length > 0) blocks.push(pending);
13467
+ result.text = blocks.join("\n\n");
13468
+ return result;
13469
+ }
13470
+
13471
+ // src/tools/agent_run.ts
13472
+ var RUN_ID_HEADER = "x-vectros-run-id";
13473
+ var MAX_INPUT_CHARS = 1e5;
13474
+ var MAX_INPUT_BYTES = 24e4;
13475
+ function encodedInputBytes(v) {
13476
+ return Buffer.byteLength(JSON.stringify(v), "utf8");
13477
+ }
13478
+ var TERMINAL_EVENT_TYPES = /* @__PURE__ */ new Set(["run.completed", "run.failed", "run.cancelled"]);
13479
+ var ENDED_STATUSES = /* @__PURE__ */ new Set(["COMPLETED", "FAILED", "CANCELLED", "EXPIRED"]);
13480
+ var inputSchema25 = {
13481
+ agentId: z25.string().min(1, "agentId must be non-empty").describe("The agent to run: an `id` from agent_list."),
13482
+ input: z25.string().min(1, "input must be non-empty").max(MAX_INPUT_CHARS, `input accepts at most ${MAX_INPUT_CHARS} characters`).refine(
13483
+ (v) => encodedInputBytes(v) <= MAX_INPUT_BYTES,
13484
+ `input accepts at most ${MAX_INPUT_BYTES} bytes as sent (a JSON string in UTF-8)`
13485
+ ).describe(
13486
+ `What the agent is asked, 1 to ${MAX_INPUT_CHARS} characters and at most ${MAX_INPUT_BYTES} bytes as sent (a JSON string in UTF-8; most control characters other than newline and tab count six bytes).`
13487
+ ),
13488
+ agentVersion: z25.number().int().min(1).optional().describe("The agent version to run. Default: its latest version."),
13489
+ maxInferenceCents: z25.number().int().min(1).optional().describe(
13490
+ "The most this run's model calls may cost, in US cents. It can only lower the agent's own budget (a higher value is refused); a value below the platform minimum is refused with errorCode `BUDGET_TOO_LOW`, whose message names the minimum. Default: the agent's budget. A run that reaches it ends `FAILED` with errorCode `BUDGET_EXCEEDED`."
13491
+ ),
13492
+ readOnly: z25.boolean().optional().describe("When true, every tool call that would change data is refused in this run. Default false."),
13493
+ idempotencyKey: z25.string().regex(/^[A-Za-z0-9._:-]{1,128}$/, "idempotencyKey is 1 to 128 letters, digits, `.`, `_`, `:` or `-`").optional().describe(
13494
+ "Makes a retried call safe: the same key with the same arguments never starts a second run; the retry returns that run's id and status (`alreadyStarted: true`) instead. Its answer text is not returned again; read how it ended with run_get. Default: a new key per call."
13495
+ )
13496
+ };
13497
+ var agentRun = ({ client, log }) => ({
13498
+ name: "agent_run",
13499
+ title: "Run an agent",
13500
+ description: "Run a stored agent (from agent_list) on one `input` and return its answer. The agent's tool calls act as you, with your own permissions, and only through the tools the agent lists; set `readOnly` to refuse every tool call that would change data. Cap the run's model cost with `maxInferenceCents` (it can only lower the agent's own budget). The run is billed: model calls against your inference balance, and a fee per run, tool calls and run time against your plan. An agent can search the web or fetch a page when its definition lists that web tool (web fetch also needs your tenant's owner to switch it on, and a run of an agent that lists `web_search` is refused while the platform has web search disabled). Returns `{ runId, agentId, agentVersion, status, terminal, reason, errorCode, text, toolCalls, charged }`; `charged` carries the run's charge and refund in milli-cents (1 cent = 1000). Progress notifications keep the call alive while the run works for a client that resets its timeout on progress; cancelling the call cancels the run once the run is named (almost at once). If `terminal` is false the result arrived before the run ended: read it with run_get, which needs `runs:r` as well. Calling again without `idempotencyKey` starts a new, billed run. Needs the `runs:c` scope.",
13501
+ inputSchema: inputSchema25,
13502
+ // Not a read: a run is billed, and its tool calls may create, change or delete data with the
13503
+ // caller's permissions, so a host should confirm it. Not idempotent: each call is a new paid run
13504
+ // unless the same idempotencyKey is passed again.
13505
+ annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
13506
+ handler: async (args, extra) => {
13507
+ const agentId = args.agentId;
13508
+ const maxInferenceCents = args.maxInferenceCents;
13509
+ const idempotencyKey = args.idempotencyKey ?? randomUUID();
13510
+ const request = {
13511
+ "Idempotency-Key": idempotencyKey,
13512
+ agentId,
13513
+ agentVersion: args.agentVersion,
13514
+ input: { text: args.input },
13515
+ budget: maxInferenceCents !== void 0 ? { maxInferenceCents } : void 0,
13516
+ readOnly: args.readOnly
13517
+ };
13518
+ const progressToken = extra._meta?.progressToken;
13519
+ let progressCount = 0;
13520
+ const onProgress = progressToken !== void 0 && extra.sendNotification ? async (message) => {
13521
+ progressCount += 1;
13522
+ await extra.sendNotification({
13523
+ method: "notifications/progress",
13524
+ params: { progressToken, progress: progressCount, message }
13525
+ });
13526
+ } : void 0;
13527
+ const streamAbort = new AbortController();
13528
+ const callSignal = extra.signal;
13529
+ let knownRunId;
13530
+ let headersReceived = false;
13531
+ let cancelRequested = false;
13532
+ let cancelSent = false;
13533
+ let runEnded = false;
13534
+ const sendCancel = () => {
13535
+ if (!cancelRequested || cancelSent || !knownRunId || runEnded) return;
13536
+ cancelSent = true;
13537
+ const id = knownRunId;
13538
+ client.agents.cancelRun({ id }).then(
13539
+ () => log.info({ tool: "agent_run", runId: id }, "agent_run cancelled by the client"),
13540
+ (err) => log.warn({ tool: "agent_run", runId: id, err: String(err) }, "agent_run cancel failed")
13541
+ );
13542
+ };
13543
+ const cancelIfNamed = () => {
13544
+ if (!cancelRequested || !headersReceived || !knownRunId) return;
13545
+ sendCancel();
13546
+ streamAbort.abort();
13547
+ };
13548
+ const onCancel = () => {
13549
+ cancelRequested = true;
13550
+ cancelIfNamed();
13551
+ };
13552
+ if (callSignal?.aborted) {
13553
+ return toolError("agent_run", new Error("The call was cancelled before the run started."));
13554
+ }
13555
+ callSignal?.addEventListener("abort", onCancel, { once: true });
13556
+ try {
13557
+ const { data: stream, rawResponse } = await client.agents.createRun(request, { abortSignal: streamAbort.signal }).withRawResponse();
13558
+ headersReceived = true;
13559
+ knownRunId = rawResponse.headers.get(RUN_ID_HEADER) ?? void 0;
13560
+ cancelIfNamed();
13561
+ const naming = async function* () {
13562
+ for await (const ev of stream) {
13563
+ if (!knownRunId && ev && typeof ev === "object") {
13564
+ const id = ev.runId;
13565
+ if (typeof id === "string" && id.length > 0) {
13566
+ knownRunId = id;
13567
+ cancelIfNamed();
13568
+ }
13569
+ }
13570
+ if (ev && typeof ev === "object") {
13571
+ const e = ev;
13572
+ if (e.terminal === true || typeof e.type === "string" && TERMINAL_EVENT_TYPES.has(e.type)) runEnded = true;
13573
+ }
13574
+ yield ev;
13575
+ }
13576
+ };
13577
+ const run = await consumeRunStream(naming(), knownRunId, onProgress);
13578
+ knownRunId ??= run.runId;
13579
+ if (run.terminal) runEnded = true;
13580
+ sendCancel();
13581
+ log.debug(
13582
+ {
13583
+ tool: "agent_run",
13584
+ runId: run.runId,
13585
+ status: run.status,
13586
+ terminal: run.terminal,
13587
+ toolCalls: run.toolCalls.length,
13588
+ textLength: run.text.length
13589
+ },
13590
+ "agent_run ok"
13591
+ );
13592
+ const body = {
13593
+ runId: run.runId,
13594
+ agentId: run.agentId ?? agentId,
13595
+ agentVersion: run.agentVersion,
13596
+ status: run.status,
13597
+ terminal: run.terminal,
13598
+ reason: run.reason,
13599
+ errorCode: run.errorCode,
13600
+ text: run.text,
13601
+ toolCalls: run.toolCalls,
13602
+ charged: run.charged
13603
+ };
13604
+ if (!run.terminal) {
13605
+ body.note = cancelRequested ? "The call was cancelled and the run was asked to stop. Read it with run_get (needs the `runs:r` scope) to see how it ended." : "The stream ended before the run did" + (run.streamError ? ` (${run.streamError})` : "") + ". The run may still be working: read it with run_get until `terminal` is true (run_get needs the `runs:r` scope).";
13606
+ }
13607
+ return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
13608
+ } catch (err) {
13609
+ const e = err;
13610
+ if (e?.body?.errorCode === "IDEMPOTENCY_IN_PROGRESS") {
13611
+ const runId = (typeof e.body.runId === "string" ? e.body.runId : void 0) ?? e.rawResponse?.headers?.get?.(RUN_ID_HEADER) ?? void 0;
13612
+ if (runId) {
13613
+ const status = typeof e.body.status === "string" ? e.body.status : void 0;
13614
+ log.info({ tool: "agent_run", runId }, "agent_run: the idempotency key already started a run");
13615
+ const body = {
13616
+ runId,
13617
+ agentId,
13618
+ status,
13619
+ // The 409 names the run's status at the time; an ended status is final.
13620
+ terminal: status !== void 0 && ENDED_STATUSES.has(status),
13621
+ alreadyStarted: true,
13622
+ note: "This idempotency key already started this run, so no new run was started. Its answer text is not returned again and cannot be read back: run_get (needs the `runs:r` scope) shows how the run ended and what it was charged, never its text. To start another run, pass a new idempotencyKey."
13623
+ };
13624
+ return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
13625
+ }
13626
+ }
13627
+ log.warn({ tool: "agent_run", agentId, err: String(err) }, "agent_run failed");
13628
+ const result = toolError("agent_run", err);
13629
+ const statusCode = err?.statusCode;
13630
+ if (typeof statusCode !== "number" || statusCode === 408 || statusCode >= 500) {
13631
+ result.content[0].text += `
13632
+ idempotencyKey: ${idempotencyKey}
13633
+ A run may have started before this error. Call agent_run again with the same arguments and this idempotencyKey: if a run started, the call names it; if not, it starts one.` + (cancelRequested ? " (The call was cancelled; a run that started could not be cancelled.)" : "");
13634
+ }
13635
+ return result;
13636
+ } finally {
13637
+ callSignal?.removeEventListener("abort", onCancel);
13638
+ }
13639
+ }
13640
+ });
13641
+ var agent_run_default = agentRun;
13642
+
13643
+ // src/tools/run_get.ts
13644
+ import { z as z26 } from "zod";
13645
+ var inputSchema26 = {
13646
+ runId: z26.string().min(1, "runId must be non-empty").describe("The run id agent_run returned (`runId`).")
13647
+ };
13648
+ var runGet = ({ client, log }) => ({
13649
+ name: "run_get",
13650
+ title: "Get an agent run",
13651
+ description: "Read one agent run by id: `status` (`RUNNING`, `COMPLETED`, `FAILED`, `CANCELLED` or `EXPIRED`), `terminal` (whether it has ended; poll until true), `reason`, `errorCode`, `steps`, its `toolCalls` (each tool and how it ended, never its arguments or result) and `usage` (what it was charged, in milli-cents). It does not return the answer text: agent_run returns that. Use it when agent_run returned `terminal: false`. Needs the `runs:r` scope, which starting a run (`runs:c`) does not include: a credential with only `runs:c` gets `403` here, and learns how its runs end only from agent_run's own result.",
13652
+ inputSchema: inputSchema26,
13653
+ // A pure read: polling a run does not change it.
13654
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },
13655
+ handler: async (args) => {
13656
+ const runId = args.runId;
13657
+ try {
13658
+ const run = await client.agents.getRun({ id: runId });
13659
+ log.debug({ tool: "run_get", runId, status: run.status, terminal: run.terminal }, "run_get ok");
13660
+ return { content: [{ type: "text", text: JSON.stringify(run, null, 2) }] };
13661
+ } catch (err) {
13662
+ log.warn({ tool: "run_get", runId, err: String(err) }, "run_get failed");
13663
+ return toolError("run_get", err);
13664
+ }
13665
+ }
13666
+ });
13667
+ var run_get_default = runGet;
13668
+
12550
13669
  // src/tools/types.ts
12551
13670
  var TOOL_NAMES = [
12552
13671
  "hybrid_search",
@@ -12571,7 +13690,10 @@ var TOOL_NAMES = [
12571
13690
  "current_identity",
12572
13691
  "document_ingest",
12573
13692
  "lookup_principal",
12574
- "version_history"
13693
+ "version_history",
13694
+ "agent_list",
13695
+ "agent_run",
13696
+ "run_get"
12575
13697
  ];
12576
13698
 
12577
13699
  // src/tools/index.ts
@@ -12598,7 +13720,10 @@ var ALL_TOOL_FACTORIES = {
12598
13720
  current_identity: current_identity_default,
12599
13721
  document_ingest: document_ingest_default,
12600
13722
  lookup_principal: lookup_principal_default,
12601
- version_history: version_history_default
13723
+ version_history: version_history_default,
13724
+ agent_list: agent_list_default,
13725
+ agent_run: agent_run_default,
13726
+ run_get: run_get_default
12602
13727
  };
12603
13728
 
12604
13729
  // src/resources/schemas.ts
@@ -12622,7 +13747,7 @@ var identityResource = ({ log, apiKey, environment }) => ({
12622
13747
  name: "identity",
12623
13748
  uri: "vectros://identity",
12624
13749
  title: "Current identity (tenant + principal scope)",
12625
- description: "The tenant + principal scope the MCP server is authenticated as. Returns the same payload as the `current_identity` tool: status, tenantId, environment, principalType, principalKeyId, principalLabel, (for scoped credentials) allowedActions + dataScope ({ userId, scopes[] }). Note: this does not yet include granted_capabilities (member-lifecycle / forensic-read / context-directory-read / delegate-mint, as of API 0.40.0, joined by delegate-principal-stamp in 0.42.0) \u2014 a separate reach dimension a scope clause can carry that /v1/ping does not report yet, so allowedActions+dataScope may understate a credential's true reach. Also reports mcpServerVersion and sdkVersion (this build's own version and the bundled @vectros-ai/sdk version). The /v1/ping backing call ships the extended shape today; the version fields are always client-derived.",
13750
+ description: "The tenant + principal scope the MCP server is authenticated as. Returns the same payload as the `current_identity` tool: status, tenantId, environment, principalType, principalKeyId, principalLabel, (for scoped credentials) allowedActions + dataScope ({ userId, scopes[] }). Note: this does not include granted_capabilities (member-lifecycle / forensic-read / context-directory-read / delegate-mint, as of API 0.40.0, joined by delegate-principal-stamp in 0.42.0 and trigger-control-plane-grant in 0.44.0) \u2014 a separate reach dimension a scope clause can carry that /v1/ping does not report, so allowedActions+dataScope may understate a credential's true reach. Also reports mcpServerVersion and sdkVersion (this build's own version and the bundled @vectros-ai/sdk version). The /v1/ping backing call ships the extended shape today; the version fields are always client-derived.",
12626
13751
  mimeType: "application/json",
12627
13752
  read: async () => {
12628
13753
  const identity = await resolveIdentity({ log, apiKey, environment });
@@ -12641,11 +13766,12 @@ var ALL_RESOURCE_FACTORIES = {
12641
13766
  };
12642
13767
 
12643
13768
  // src/zod-to-json-schema.ts
12644
- import { z as z24 } from "zod";
13769
+ import { z as z27 } from "zod";
12645
13770
  function zodShapeToJsonSchema(shape) {
12646
13771
  const properties = {};
12647
13772
  const required = [];
12648
- for (const [name, schema] of Object.entries(shape)) {
13773
+ for (const [name, entry] of Object.entries(shape)) {
13774
+ const schema = entry;
12649
13775
  properties[name] = zodTypeToJsonSchema(schema);
12650
13776
  if (!schema.isOptional()) required.push(name);
12651
13777
  }
@@ -12654,43 +13780,45 @@ function zodShapeToJsonSchema(shape) {
12654
13780
  return out;
12655
13781
  }
12656
13782
  function zodTypeToJsonSchema(schema) {
12657
- const description = schema.description;
13783
+ const descriptionOf = (s) => s.description;
13784
+ let description = descriptionOf(schema);
12658
13785
  let current = schema;
12659
- while (current instanceof z24.ZodOptional || current instanceof z24.ZodDefault || current instanceof z24.ZodNullable) {
13786
+ while (current instanceof z27.ZodOptional || current instanceof z27.ZodDefault || current instanceof z27.ZodNullable) {
12660
13787
  current = current._def.innerType;
13788
+ description ??= descriptionOf(current);
12661
13789
  }
12662
13790
  const base = description ? { description } : {};
12663
- if (current instanceof z24.ZodString) {
13791
+ if (current instanceof z27.ZodString) {
12664
13792
  return { ...base, type: "string" };
12665
13793
  }
12666
- if (current instanceof z24.ZodNumber) {
13794
+ if (current instanceof z27.ZodNumber) {
12667
13795
  return { ...base, type: "number" };
12668
13796
  }
12669
- if (current instanceof z24.ZodBoolean) {
13797
+ if (current instanceof z27.ZodBoolean) {
12670
13798
  return { ...base, type: "boolean" };
12671
13799
  }
12672
- if (current instanceof z24.ZodEnum) {
13800
+ if (current instanceof z27.ZodEnum) {
12673
13801
  return {
12674
13802
  ...base,
12675
13803
  type: "string",
12676
13804
  enum: current.options
12677
13805
  };
12678
13806
  }
12679
- if (current instanceof z24.ZodArray) {
13807
+ if (current instanceof z27.ZodArray) {
12680
13808
  return {
12681
13809
  ...base,
12682
13810
  type: "array",
12683
13811
  items: zodTypeToJsonSchema(current.element)
12684
13812
  };
12685
13813
  }
12686
- if (current instanceof z24.ZodObject) {
13814
+ if (current instanceof z27.ZodObject) {
12687
13815
  return {
12688
13816
  ...base,
12689
13817
  ...zodShapeToJsonSchema(current.shape)
12690
13818
  };
12691
13819
  }
12692
- if (current instanceof z24.ZodRecord) {
12693
- const valueType = current._def.valueType;
13820
+ if (current instanceof z27.ZodRecord) {
13821
+ const valueType = current.valueType;
12694
13822
  return {
12695
13823
  ...base,
12696
13824
  type: "object",
@@ -12818,7 +13946,7 @@ var VectrosMCPServer = class {
12818
13946
  if (!tool) {
12819
13947
  result = toolError(req.params.name ?? "unknown", new Error("No such tool."));
12820
13948
  } else {
12821
- const parsed = z25.object(tool.inputSchema).strict().safeParse(req.params.arguments ?? {});
13949
+ const parsed = z28.object(tool.inputSchema).strict().safeParse(req.params.arguments ?? {});
12822
13950
  if (!parsed.success) {
12823
13951
  result = toolError(tool.name, new Error(formatArgError(tool, parsed.error)));
12824
13952
  } else {
@@ -12881,7 +14009,7 @@ var VectrosMCPServer = class {
12881
14009
  *
12882
14010
  * If `validateOnStart` (default true) is enabled, performs a
12883
14011
  * GET /v1/ping check BEFORE wiring the transport. On failure,
12884
- * throws — the partner's MCP client sees a startup error instead
14012
+ * throws — your MCP client sees a startup error instead
12885
14013
  * of a confusing "tools work but the first call 401s" experience.
12886
14014
  */
12887
14015
  async connect(transport) {