@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/index.js CHANGED
@@ -42,7 +42,7 @@ module.exports = __toCommonJS(index_exports);
42
42
  // src/server.ts
43
43
  var import_server = require("@modelcontextprotocol/sdk/server/index.js");
44
44
 
45
- // ../../node_modules/@vectros-ai/sdk/dist/index.mjs
45
+ // node_modules/@vectros-ai/sdk/dist/index.mjs
46
46
  var __defProp2 = Object.defineProperty;
47
47
  var __export2 = (target, all) => {
48
48
  for (var name in all)
@@ -57,10 +57,13 @@ __export2(api_exports, {
57
57
  BatchWriteRequest: () => BatchWriteRequest,
58
58
  BatchWriteResult: () => BatchWriteResult,
59
59
  ChatMessage: () => ChatMessage,
60
+ ChatRequest: () => ChatRequest,
60
61
  ConflictError: () => ConflictError,
61
62
  ContentDeltaEvent: () => ContentDeltaEvent,
62
63
  ContentTooLargeError: () => ContentTooLargeError,
64
+ DocumentAskRequest: () => DocumentAskRequest,
63
65
  DocumentContextEvent: () => DocumentContextEvent,
66
+ DocumentExtraction: () => DocumentExtraction,
64
67
  DocumentLookupRequest: () => DocumentLookupRequest,
65
68
  DocumentPatchRequest: () => DocumentPatchRequest,
66
69
  DocumentRequest: () => DocumentRequest,
@@ -90,8 +93,10 @@ __export2(api_exports, {
90
93
  NotImplementedError: () => NotImplementedError,
91
94
  PaymentRequiredError: () => PaymentRequiredError,
92
95
  PingResponse: () => PingResponse,
96
+ RagRequest: () => RagRequest,
93
97
  RagSearch: () => RagSearch,
94
98
  ReadAccessLogResponse: () => ReadAccessLogResponse,
99
+ ReasoningDeltaEvent: () => ReasoningDeltaEvent,
95
100
  RecordLookupRequest: () => RecordLookupRequest,
96
101
  RecordRequest: () => RecordRequest,
97
102
  RecordResponse: () => RecordResponse,
@@ -111,6 +116,7 @@ __export2(api_exports, {
111
116
  UserExistsResponse: () => UserExistsResponse,
112
117
  UserRequest: () => UserRequest,
113
118
  UserResponse: () => UserResponse,
119
+ agents: () => agents_exports,
114
120
  auth: () => auth_exports,
115
121
  compliance: () => compliance_exports,
116
122
  documents: () => documents_exports,
@@ -376,6 +382,7 @@ var UnprocessableEntityError = class extends VectrosError {
376
382
  this.name = this.constructor.name;
377
383
  }
378
384
  };
385
+ var agents_exports = {};
379
386
  var auth_exports = {};
380
387
  var ErasureRequest;
381
388
  ((ErasureRequest2) => {
@@ -447,7 +454,33 @@ var ListUsersRequestOrder = {
447
454
  Asc: "asc",
448
455
  Desc: "desc"
449
456
  };
457
+ var ChatRequest;
458
+ ((ChatRequest2) => {
459
+ ChatRequest2.Reasoning = {
460
+ Omit: "omit",
461
+ Stream: "stream"
462
+ };
463
+ })(ChatRequest || (ChatRequest = {}));
464
+ var DocumentAskRequest;
465
+ ((DocumentAskRequest2) => {
466
+ DocumentAskRequest2.Reasoning = {
467
+ Omit: "omit",
468
+ Stream: "stream"
469
+ };
470
+ })(DocumentAskRequest || (DocumentAskRequest = {}));
471
+ var RagRequest;
472
+ ((RagRequest2) => {
473
+ RagRequest2.Reasoning = {
474
+ Omit: "omit",
475
+ Stream: "stream"
476
+ };
477
+ })(RagRequest || (RagRequest = {}));
450
478
  var inference_exports = {};
479
+ __export2(inference_exports, {
480
+ ChatRequest: () => ChatRequest,
481
+ DocumentAskRequest: () => DocumentAskRequest,
482
+ RagRequest: () => RagRequest
483
+ });
451
484
  var BatchWriteRequest;
452
485
  ((BatchWriteRequest2) => {
453
486
  BatchWriteRequest2.Atomicity = {
@@ -554,6 +587,18 @@ var DocumentContextEvent;
554
587
  DocumentContext: "document_context"
555
588
  };
556
589
  })(DocumentContextEvent || (DocumentContextEvent = {}));
590
+ var DocumentExtraction;
591
+ ((DocumentExtraction2) => {
592
+ DocumentExtraction2.Outcome = {
593
+ Ok: "OK",
594
+ Truncated: "TRUNCATED",
595
+ NoText: "NO_TEXT",
596
+ Encrypted: "ENCRYPTED",
597
+ Unsupported: "UNSUPPORTED",
598
+ TooLarge: "TOO_LARGE",
599
+ Unreadable: "UNREADABLE"
600
+ };
601
+ })(DocumentExtraction || (DocumentExtraction = {}));
557
602
  var DocumentRequest;
558
603
  ((DocumentRequest2) => {
559
604
  DocumentRequest2.IndexMode = {
@@ -720,6 +765,12 @@ var ReadAccessLogResponse;
720
765
  Rag: "rag"
721
766
  };
722
767
  })(ReadAccessLogResponse || (ReadAccessLogResponse = {}));
768
+ var ReasoningDeltaEvent;
769
+ ((ReasoningDeltaEvent2) => {
770
+ ReasoningDeltaEvent2.Event = {
771
+ ReasoningDelta: "reasoning_delta"
772
+ };
773
+ })(ReasoningDeltaEvent || (ReasoningDeltaEvent = {}));
723
774
  var RecordRequest;
724
775
  ((RecordRequest2) => {
725
776
  RecordRequest2.Status = {
@@ -1853,13 +1904,13 @@ function joinPathSegments(left, right) {
1853
1904
  }
1854
1905
  return `${left}/${right}`;
1855
1906
  }
1856
- function trimSlashes(str) {
1857
- if (!str) return str;
1907
+ function trimSlashes(str2) {
1908
+ if (!str2) return str2;
1858
1909
  let start = 0;
1859
- let end = str.length;
1860
- if (str.startsWith("/")) start = 1;
1861
- if (str.endsWith("/")) end = str.length - 1;
1862
- return start === 0 && end === str.length ? str : str.slice(start, end);
1910
+ let end = str2.length;
1911
+ if (str2.startsWith("/")) start = 1;
1912
+ if (str2.endsWith("/")) end = str2.length - 1;
1913
+ return start === 0 && end === str2.length ? str2 : str2.slice(start, end);
1863
1914
  }
1864
1915
  var Supplier = {
1865
1916
  get: async (supplier) => {
@@ -2282,140 +2333,767 @@ var QueryStringBuilder = class {
2282
2333
  }
2283
2334
  }
2284
2335
  }
2285
- return this;
2336
+ return this;
2337
+ }
2338
+ /**
2339
+ * Returns the assembled query string (without the leading `?`).
2340
+ * Returns an empty string when no parameters were added.
2341
+ */
2342
+ build() {
2343
+ return [...this.parts.values()].join("&");
2344
+ }
2345
+ };
2346
+ var TOKEN_PARAM = "token";
2347
+ var BearerAuthProvider = class _BearerAuthProvider {
2348
+ constructor(options) {
2349
+ this.options = options;
2350
+ }
2351
+ static canCreate(options) {
2352
+ return options?.[TOKEN_PARAM] != null;
2353
+ }
2354
+ async getAuthRequest({
2355
+ endpointMetadata
2356
+ } = {}) {
2357
+ const token = await Supplier.get(this.options[TOKEN_PARAM]);
2358
+ if (token == null) {
2359
+ throw new VectrosError({
2360
+ message: _BearerAuthProvider.AUTH_CONFIG_ERROR_MESSAGE
2361
+ });
2362
+ }
2363
+ return {
2364
+ headers: { Authorization: `Bearer ${token}` }
2365
+ };
2366
+ }
2367
+ };
2368
+ ((BearerAuthProvider2) => {
2369
+ BearerAuthProvider2.AUTH_SCHEME = "BearerAuth";
2370
+ BearerAuthProvider2.AUTH_CONFIG_ERROR_MESSAGE = `Please provide '${TOKEN_PARAM}' when initializing the client`;
2371
+ function createInstance(options) {
2372
+ return new BearerAuthProvider2(options);
2373
+ }
2374
+ BearerAuthProvider2.createInstance = createInstance;
2375
+ })(BearerAuthProvider || (BearerAuthProvider = {}));
2376
+ function mergeHeaders(...headersArray) {
2377
+ const result = {};
2378
+ for (const [key, value] of headersArray.filter((headers) => headers != null).flatMap((headers) => Object.entries(headers))) {
2379
+ const insensitiveKey = key.toLowerCase();
2380
+ if (value != null) {
2381
+ result[insensitiveKey] = value;
2382
+ } else if (insensitiveKey in result) {
2383
+ delete result[insensitiveKey];
2384
+ }
2385
+ }
2386
+ return result;
2387
+ }
2388
+ function mergeOnlyDefinedHeaders(...headersArray) {
2389
+ const result = {};
2390
+ for (const [key, value] of headersArray.filter((headers) => headers != null).flatMap((headers) => Object.entries(headers))) {
2391
+ const insensitiveKey = key.toLowerCase();
2392
+ if (value != null) {
2393
+ result[insensitiveKey] = value;
2394
+ }
2395
+ }
2396
+ return result;
2397
+ }
2398
+ function normalizeClientOptions(options) {
2399
+ const headers = mergeHeaders(
2400
+ {
2401
+ "X-Fern-Language": "JavaScript",
2402
+ "X-Fern-Runtime": RUNTIME.type,
2403
+ "X-Fern-Runtime-Version": RUNTIME.version
2404
+ },
2405
+ options?.headers
2406
+ );
2407
+ return {
2408
+ ...options,
2409
+ logging: logging_exports.createLogger(options?.logging),
2410
+ headers
2411
+ };
2412
+ }
2413
+ function normalizeClientOptionsWithAuth(options) {
2414
+ const normalized = normalizeClientOptions(options);
2415
+ if (options.auth === false) {
2416
+ normalized.authProvider = new NoOpAuthProvider();
2417
+ return normalized;
2418
+ }
2419
+ if (options.auth != null) {
2420
+ if (typeof options.auth === "function") {
2421
+ normalized.authProvider = { getAuthRequest: options.auth };
2422
+ return normalized;
2423
+ }
2424
+ if (isAuthProvider(options.auth)) {
2425
+ normalized.authProvider = options.auth;
2426
+ return normalized;
2427
+ }
2428
+ Object.assign(normalized, options.auth);
2429
+ }
2430
+ const normalizedWithNoOpAuthProvider = withNoOpAuthProvider(normalized);
2431
+ normalized.authProvider ?? (normalized.authProvider = new BearerAuthProvider(normalizedWithNoOpAuthProvider));
2432
+ return normalized;
2433
+ }
2434
+ function withNoOpAuthProvider(options) {
2435
+ return {
2436
+ ...options,
2437
+ authProvider: new NoOpAuthProvider()
2438
+ };
2439
+ }
2440
+ function handleNonStatusCodeError(error, rawResponse, method, path) {
2441
+ switch (error.reason) {
2442
+ case "non-json":
2443
+ throw new VectrosError({
2444
+ statusCode: error.statusCode,
2445
+ body: error.rawBody,
2446
+ rawResponse
2447
+ });
2448
+ case "body-is-null":
2449
+ throw new VectrosError({
2450
+ statusCode: error.statusCode,
2451
+ rawResponse
2452
+ });
2453
+ case "timeout":
2454
+ throw new VectrosTimeoutError(`Timeout exceeded when calling ${method} ${path}.`, {
2455
+ cause: error.cause
2456
+ });
2457
+ case "unknown":
2458
+ throw new VectrosError({
2459
+ message: error.errorMessage,
2460
+ rawResponse,
2461
+ cause: error.cause
2462
+ });
2463
+ default:
2464
+ throw new VectrosError({
2465
+ message: "Unknown error",
2466
+ rawResponse
2467
+ });
2468
+ }
2469
+ }
2470
+ var AgentsClient = class {
2471
+ constructor(options) {
2472
+ this._options = normalizeClientOptionsWithAuth(options);
2473
+ }
2474
+ /**
2475
+ * 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`.
2476
+ *
2477
+ * @param {Vectros.ListAgentsRequest} request
2478
+ * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration.
2479
+ *
2480
+ * @throws {@link Vectros.ForbiddenError}
2481
+ *
2482
+ * @example
2483
+ * await client.agents.listAgents()
2484
+ */
2485
+ listAgents(request = {}, requestOptions) {
2486
+ return HttpResponsePromise.fromPromise(this.__listAgents(request, requestOptions));
2487
+ }
2488
+ async __listAgents(request = {}, requestOptions) {
2489
+ const { contextId, includeRetired, startFrom, limit } = request;
2490
+ const _queryParams = {
2491
+ contextId,
2492
+ includeRetired,
2493
+ startFrom,
2494
+ limit
2495
+ };
2496
+ const _authRequest = await this._options.authProvider.getAuthRequest();
2497
+ const _headers = mergeHeaders(
2498
+ _authRequest.headers,
2499
+ this._options?.headers,
2500
+ requestOptions?.headers
2501
+ );
2502
+ const _response = await fetcher({
2503
+ url: url_exports.join(
2504
+ await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
2505
+ "v1/agents"
2506
+ ),
2507
+ method: "GET",
2508
+ headers: _headers,
2509
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
2510
+ timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
2511
+ maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
2512
+ abortSignal: requestOptions?.abortSignal,
2513
+ fetchFn: this._options?.fetch,
2514
+ logging: this._options.logging
2515
+ });
2516
+ if (_response.ok) {
2517
+ return { data: _response.body, rawResponse: _response.rawResponse };
2518
+ }
2519
+ if (_response.error.reason === "status-code") {
2520
+ switch (_response.error.statusCode) {
2521
+ case 403:
2522
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
2523
+ default:
2524
+ throw new VectrosError({
2525
+ statusCode: _response.error.statusCode,
2526
+ body: _response.error.body,
2527
+ rawResponse: _response.rawResponse
2528
+ });
2529
+ }
2530
+ }
2531
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/agents");
2532
+ }
2533
+ /**
2534
+ * 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`).
2535
+ *
2536
+ * @param {Vectros.CreateAgentRequest} request
2537
+ * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration.
2538
+ *
2539
+ * @throws {@link Vectros.BadRequestError}
2540
+ * @throws {@link Vectros.ForbiddenError}
2541
+ * @throws {@link Vectros.ConflictError}
2542
+ * @throws {@link Vectros.TooManyRequestsError}
2543
+ *
2544
+ * @example
2545
+ * await client.agents.createAgent({
2546
+ * body: {
2547
+ * model: "claude-sonnet-5-5"
2548
+ * }
2549
+ * })
2550
+ */
2551
+ createAgent(request, requestOptions) {
2552
+ return HttpResponsePromise.fromPromise(this.__createAgent(request, requestOptions));
2553
+ }
2554
+ async __createAgent(request, requestOptions) {
2555
+ const { upsert, contextId, body: _body } = request;
2556
+ const _queryParams = {
2557
+ upsert,
2558
+ contextId
2559
+ };
2560
+ const _authRequest = await this._options.authProvider.getAuthRequest();
2561
+ const _headers = mergeHeaders(
2562
+ _authRequest.headers,
2563
+ this._options?.headers,
2564
+ requestOptions?.headers
2565
+ );
2566
+ const _response = await fetcher({
2567
+ url: url_exports.join(
2568
+ await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
2569
+ "v1/agents"
2570
+ ),
2571
+ method: "POST",
2572
+ headers: _headers,
2573
+ contentType: "application/json",
2574
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
2575
+ requestType: "json",
2576
+ body: _body,
2577
+ timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
2578
+ maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
2579
+ abortSignal: requestOptions?.abortSignal,
2580
+ fetchFn: this._options?.fetch,
2581
+ logging: this._options.logging
2582
+ });
2583
+ if (_response.ok) {
2584
+ return { data: _response.body, rawResponse: _response.rawResponse };
2585
+ }
2586
+ if (_response.error.reason === "status-code") {
2587
+ switch (_response.error.statusCode) {
2588
+ case 400:
2589
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
2590
+ case 403:
2591
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
2592
+ case 409:
2593
+ throw new ConflictError(_response.error.body, _response.rawResponse);
2594
+ case 429:
2595
+ throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
2596
+ default:
2597
+ throw new VectrosError({
2598
+ statusCode: _response.error.statusCode,
2599
+ body: _response.error.body,
2600
+ rawResponse: _response.rawResponse
2601
+ });
2602
+ }
2603
+ }
2604
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/agents");
2605
+ }
2606
+ /**
2607
+ * Returns the agent at its latest version, or at `version`. Requires the `agents:r` scope.
2608
+ *
2609
+ * @param {Vectros.GetAgentRequest} request
2610
+ * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration.
2611
+ *
2612
+ * @throws {@link Vectros.ForbiddenError}
2613
+ * @throws {@link Vectros.NotFoundError}
2614
+ *
2615
+ * @example
2616
+ * await client.agents.getAgent({
2617
+ * id: "id"
2618
+ * })
2619
+ */
2620
+ getAgent(request, requestOptions) {
2621
+ return HttpResponsePromise.fromPromise(this.__getAgent(request, requestOptions));
2622
+ }
2623
+ async __getAgent(request, requestOptions) {
2624
+ const { id, contextId, version } = request;
2625
+ const _queryParams = {
2626
+ contextId,
2627
+ version
2628
+ };
2629
+ const _authRequest = await this._options.authProvider.getAuthRequest();
2630
+ const _headers = mergeHeaders(
2631
+ _authRequest.headers,
2632
+ this._options?.headers,
2633
+ requestOptions?.headers
2634
+ );
2635
+ const _response = await fetcher({
2636
+ url: url_exports.join(
2637
+ await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
2638
+ `v1/agents/${url_exports.encodePathParam(id)}`
2639
+ ),
2640
+ method: "GET",
2641
+ headers: _headers,
2642
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
2643
+ timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
2644
+ maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
2645
+ abortSignal: requestOptions?.abortSignal,
2646
+ fetchFn: this._options?.fetch,
2647
+ logging: this._options.logging
2648
+ });
2649
+ if (_response.ok) {
2650
+ return { data: _response.body, rawResponse: _response.rawResponse };
2651
+ }
2652
+ if (_response.error.reason === "status-code") {
2653
+ switch (_response.error.statusCode) {
2654
+ case 403:
2655
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
2656
+ case 404:
2657
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
2658
+ default:
2659
+ throw new VectrosError({
2660
+ statusCode: _response.error.statusCode,
2661
+ body: _response.error.body,
2662
+ rawResponse: _response.rawResponse
2663
+ });
2664
+ }
2665
+ }
2666
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/agents/{id}");
2667
+ }
2668
+ /**
2669
+ * 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.
2670
+ *
2671
+ * @param {Vectros.UpdateAgentRequest} request
2672
+ * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration.
2673
+ *
2674
+ * @throws {@link Vectros.BadRequestError}
2675
+ * @throws {@link Vectros.ForbiddenError}
2676
+ * @throws {@link Vectros.NotFoundError}
2677
+ * @throws {@link Vectros.ConflictError}
2678
+ * @throws {@link Vectros.TooManyRequestsError}
2679
+ *
2680
+ * @example
2681
+ * await client.agents.updateAgent({
2682
+ * id: "id",
2683
+ * body: {
2684
+ * model: "claude-sonnet-5-5"
2685
+ * }
2686
+ * })
2687
+ */
2688
+ updateAgent(request, requestOptions) {
2689
+ return HttpResponsePromise.fromPromise(this.__updateAgent(request, requestOptions));
2690
+ }
2691
+ async __updateAgent(request, requestOptions) {
2692
+ const { id, restore, contextId, body: _body } = request;
2693
+ const _queryParams = {
2694
+ restore,
2695
+ contextId
2696
+ };
2697
+ const _authRequest = await this._options.authProvider.getAuthRequest();
2698
+ const _headers = mergeHeaders(
2699
+ _authRequest.headers,
2700
+ this._options?.headers,
2701
+ requestOptions?.headers
2702
+ );
2703
+ const _response = await fetcher({
2704
+ url: url_exports.join(
2705
+ await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
2706
+ `v1/agents/${url_exports.encodePathParam(id)}`
2707
+ ),
2708
+ method: "PUT",
2709
+ headers: _headers,
2710
+ contentType: "application/json",
2711
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
2712
+ requestType: "json",
2713
+ body: _body,
2714
+ timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
2715
+ maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
2716
+ abortSignal: requestOptions?.abortSignal,
2717
+ fetchFn: this._options?.fetch,
2718
+ logging: this._options.logging
2719
+ });
2720
+ if (_response.ok) {
2721
+ return { data: _response.body, rawResponse: _response.rawResponse };
2722
+ }
2723
+ if (_response.error.reason === "status-code") {
2724
+ switch (_response.error.statusCode) {
2725
+ case 400:
2726
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
2727
+ case 403:
2728
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
2729
+ case 404:
2730
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
2731
+ case 409:
2732
+ throw new ConflictError(_response.error.body, _response.rawResponse);
2733
+ case 429:
2734
+ throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
2735
+ default:
2736
+ throw new VectrosError({
2737
+ statusCode: _response.error.statusCode,
2738
+ body: _response.error.body,
2739
+ rawResponse: _response.rawResponse
2740
+ });
2741
+ }
2742
+ }
2743
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "PUT", "/v1/agents/{id}");
2744
+ }
2745
+ /**
2746
+ * 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.
2747
+ *
2748
+ * @param {Vectros.DeleteAgentRequest} request
2749
+ * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration.
2750
+ *
2751
+ * @throws {@link Vectros.BadRequestError}
2752
+ * @throws {@link Vectros.ForbiddenError}
2753
+ * @throws {@link Vectros.NotFoundError}
2754
+ * @throws {@link Vectros.ConflictError}
2755
+ * @throws {@link Vectros.TooManyRequestsError}
2756
+ *
2757
+ * @example
2758
+ * await client.agents.deleteAgent({
2759
+ * id: "id"
2760
+ * })
2761
+ */
2762
+ deleteAgent(request, requestOptions) {
2763
+ return HttpResponsePromise.fromPromise(this.__deleteAgent(request, requestOptions));
2764
+ }
2765
+ async __deleteAgent(request, requestOptions) {
2766
+ const { id, purge, version, contextId } = request;
2767
+ const _queryParams = {
2768
+ purge,
2769
+ version,
2770
+ contextId
2771
+ };
2772
+ const _authRequest = await this._options.authProvider.getAuthRequest();
2773
+ const _headers = mergeHeaders(
2774
+ _authRequest.headers,
2775
+ this._options?.headers,
2776
+ requestOptions?.headers
2777
+ );
2778
+ const _response = await fetcher({
2779
+ url: url_exports.join(
2780
+ await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
2781
+ `v1/agents/${url_exports.encodePathParam(id)}`
2782
+ ),
2783
+ method: "DELETE",
2784
+ headers: _headers,
2785
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
2786
+ timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
2787
+ maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
2788
+ abortSignal: requestOptions?.abortSignal,
2789
+ fetchFn: this._options?.fetch,
2790
+ logging: this._options.logging
2791
+ });
2792
+ if (_response.ok) {
2793
+ return { data: _response.body, rawResponse: _response.rawResponse };
2794
+ }
2795
+ if (_response.error.reason === "status-code") {
2796
+ switch (_response.error.statusCode) {
2797
+ case 400:
2798
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
2799
+ case 403:
2800
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
2801
+ case 404:
2802
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
2803
+ case 409:
2804
+ throw new ConflictError(_response.error.body, _response.rawResponse);
2805
+ case 429:
2806
+ throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
2807
+ default:
2808
+ throw new VectrosError({
2809
+ statusCode: _response.error.statusCode,
2810
+ body: _response.error.body,
2811
+ rawResponse: _response.rawResponse
2812
+ });
2813
+ }
2814
+ }
2815
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "DELETE", "/v1/agents/{id}");
2816
+ }
2817
+ /**
2818
+ * 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.
2819
+ *
2820
+ * @param {Vectros.ListAgentVersionsRequest} request
2821
+ * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration.
2822
+ *
2823
+ * @throws {@link Vectros.ForbiddenError}
2824
+ * @throws {@link Vectros.NotFoundError}
2825
+ *
2826
+ * @example
2827
+ * await client.agents.listAgentVersions({
2828
+ * id: "id"
2829
+ * })
2830
+ */
2831
+ listAgentVersions(request, requestOptions) {
2832
+ return HttpResponsePromise.fromPromise(this.__listAgentVersions(request, requestOptions));
2833
+ }
2834
+ async __listAgentVersions(request, requestOptions) {
2835
+ const { id, contextId, includeContent, startFrom, limit } = request;
2836
+ const _queryParams = {
2837
+ contextId,
2838
+ includeContent,
2839
+ startFrom,
2840
+ limit
2841
+ };
2842
+ const _authRequest = await this._options.authProvider.getAuthRequest();
2843
+ const _headers = mergeHeaders(
2844
+ _authRequest.headers,
2845
+ this._options?.headers,
2846
+ requestOptions?.headers
2847
+ );
2848
+ const _response = await fetcher({
2849
+ url: url_exports.join(
2850
+ await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
2851
+ `v1/agents/${url_exports.encodePathParam(id)}/versions`
2852
+ ),
2853
+ method: "GET",
2854
+ headers: _headers,
2855
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
2856
+ timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
2857
+ maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
2858
+ abortSignal: requestOptions?.abortSignal,
2859
+ fetchFn: this._options?.fetch,
2860
+ logging: this._options.logging
2861
+ });
2862
+ if (_response.ok) {
2863
+ return { data: _response.body, rawResponse: _response.rawResponse };
2864
+ }
2865
+ if (_response.error.reason === "status-code") {
2866
+ switch (_response.error.statusCode) {
2867
+ case 403:
2868
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
2869
+ case 404:
2870
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
2871
+ default:
2872
+ throw new VectrosError({
2873
+ statusCode: _response.error.statusCode,
2874
+ body: _response.error.body,
2875
+ rawResponse: _response.rawResponse
2876
+ });
2877
+ }
2878
+ }
2879
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/agents/{id}/versions");
2880
+ }
2881
+ /**
2882
+ * 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.
2883
+ *
2884
+ * @param {Vectros.CancelRunRequest} request
2885
+ * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration.
2886
+ *
2887
+ * @throws {@link Vectros.BadRequestError}
2888
+ * @throws {@link Vectros.UnauthorizedError}
2889
+ * @throws {@link Vectros.ForbiddenError}
2890
+ * @throws {@link Vectros.NotFoundError}
2891
+ * @throws {@link Vectros.TooManyRequestsError}
2892
+ *
2893
+ * @example
2894
+ * await client.agents.cancelRun({
2895
+ * id: "id"
2896
+ * })
2897
+ */
2898
+ cancelRun(request, requestOptions) {
2899
+ return HttpResponsePromise.fromPromise(this.__cancelRun(request, requestOptions));
2900
+ }
2901
+ async __cancelRun(request, requestOptions) {
2902
+ const { id, contextId } = request;
2903
+ const _queryParams = {
2904
+ contextId
2905
+ };
2906
+ const _authRequest = await this._options.authProvider.getAuthRequest();
2907
+ const _headers = mergeHeaders(
2908
+ _authRequest.headers,
2909
+ this._options?.headers,
2910
+ requestOptions?.headers
2911
+ );
2912
+ const _response = await fetcher({
2913
+ url: url_exports.join(
2914
+ await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
2915
+ `v1/runs/${url_exports.encodePathParam(id)}/cancel`
2916
+ ),
2917
+ method: "POST",
2918
+ headers: _headers,
2919
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
2920
+ timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
2921
+ maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
2922
+ abortSignal: requestOptions?.abortSignal,
2923
+ fetchFn: this._options?.fetch,
2924
+ logging: this._options.logging
2925
+ });
2926
+ if (_response.ok) {
2927
+ return { data: _response.body, rawResponse: _response.rawResponse };
2928
+ }
2929
+ if (_response.error.reason === "status-code") {
2930
+ switch (_response.error.statusCode) {
2931
+ case 400:
2932
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
2933
+ case 401:
2934
+ throw new UnauthorizedError(_response.error.body, _response.rawResponse);
2935
+ case 403:
2936
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
2937
+ case 404:
2938
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
2939
+ case 429:
2940
+ throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
2941
+ default:
2942
+ throw new VectrosError({
2943
+ statusCode: _response.error.statusCode,
2944
+ body: _response.error.body,
2945
+ rawResponse: _response.rawResponse
2946
+ });
2947
+ }
2948
+ }
2949
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/runs/{id}/cancel");
2950
+ }
2951
+ /**
2952
+ * 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.
2953
+ *
2954
+ * @param {Vectros.GetRunRequest} request
2955
+ * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration.
2956
+ *
2957
+ * @throws {@link Vectros.BadRequestError}
2958
+ * @throws {@link Vectros.UnauthorizedError}
2959
+ * @throws {@link Vectros.ForbiddenError}
2960
+ * @throws {@link Vectros.NotFoundError}
2961
+ *
2962
+ * @example
2963
+ * await client.agents.getRun({
2964
+ * id: "id"
2965
+ * })
2966
+ */
2967
+ getRun(request, requestOptions) {
2968
+ return HttpResponsePromise.fromPromise(this.__getRun(request, requestOptions));
2969
+ }
2970
+ async __getRun(request, requestOptions) {
2971
+ const { id, contextId } = request;
2972
+ const _queryParams = {
2973
+ contextId
2974
+ };
2975
+ const _authRequest = await this._options.authProvider.getAuthRequest();
2976
+ const _headers = mergeHeaders(
2977
+ _authRequest.headers,
2978
+ this._options?.headers,
2979
+ requestOptions?.headers
2980
+ );
2981
+ const _response = await fetcher({
2982
+ url: url_exports.join(
2983
+ await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
2984
+ `v1/runs/${url_exports.encodePathParam(id)}`
2985
+ ),
2986
+ method: "GET",
2987
+ headers: _headers,
2988
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
2989
+ timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
2990
+ maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
2991
+ abortSignal: requestOptions?.abortSignal,
2992
+ fetchFn: this._options?.fetch,
2993
+ logging: this._options.logging
2994
+ });
2995
+ if (_response.ok) {
2996
+ return { data: _response.body, rawResponse: _response.rawResponse };
2997
+ }
2998
+ if (_response.error.reason === "status-code") {
2999
+ switch (_response.error.statusCode) {
3000
+ case 400:
3001
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
3002
+ case 401:
3003
+ throw new UnauthorizedError(_response.error.body, _response.rawResponse);
3004
+ case 403:
3005
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
3006
+ case 404:
3007
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
3008
+ default:
3009
+ throw new VectrosError({
3010
+ statusCode: _response.error.statusCode,
3011
+ body: _response.error.body,
3012
+ rawResponse: _response.rawResponse
3013
+ });
3014
+ }
3015
+ }
3016
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/runs/{id}");
2286
3017
  }
2287
3018
  /**
2288
- * Returns the assembled query string (without the leading `?`).
2289
- * Returns an empty string when no parameters were added.
3019
+ * 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.
2290
3020
  */
2291
- build() {
2292
- return [...this.parts.values()].join("&");
2293
- }
2294
- };
2295
- var TOKEN_PARAM = "token";
2296
- var BearerAuthProvider = class _BearerAuthProvider {
2297
- constructor(options) {
2298
- this.options = options;
2299
- }
2300
- static canCreate(options) {
2301
- return options?.[TOKEN_PARAM] != null;
2302
- }
2303
- async getAuthRequest({
2304
- endpointMetadata
2305
- } = {}) {
2306
- const token = await Supplier.get(this.options[TOKEN_PARAM]);
2307
- if (token == null) {
2308
- throw new VectrosError({
2309
- message: _BearerAuthProvider.AUTH_CONFIG_ERROR_MESSAGE
2310
- });
2311
- }
2312
- return {
2313
- headers: { Authorization: `Bearer ${token}` }
2314
- };
2315
- }
2316
- };
2317
- ((BearerAuthProvider2) => {
2318
- BearerAuthProvider2.AUTH_SCHEME = "BearerAuth";
2319
- BearerAuthProvider2.AUTH_CONFIG_ERROR_MESSAGE = `Please provide '${TOKEN_PARAM}' when initializing the client`;
2320
- function createInstance(options) {
2321
- return new BearerAuthProvider2(options);
2322
- }
2323
- BearerAuthProvider2.createInstance = createInstance;
2324
- })(BearerAuthProvider || (BearerAuthProvider = {}));
2325
- function mergeHeaders(...headersArray) {
2326
- const result = {};
2327
- for (const [key, value] of headersArray.filter((headers) => headers != null).flatMap((headers) => Object.entries(headers))) {
2328
- const insensitiveKey = key.toLowerCase();
2329
- if (value != null) {
2330
- result[insensitiveKey] = value;
2331
- } else if (insensitiveKey in result) {
2332
- delete result[insensitiveKey];
2333
- }
2334
- }
2335
- return result;
2336
- }
2337
- function mergeOnlyDefinedHeaders(...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
- }
2344
- }
2345
- return result;
2346
- }
2347
- function normalizeClientOptions(options) {
2348
- const headers = mergeHeaders(
2349
- {
2350
- "X-Fern-Language": "JavaScript",
2351
- "X-Fern-Runtime": RUNTIME.type,
2352
- "X-Fern-Runtime-Version": RUNTIME.version
2353
- },
2354
- options?.headers
2355
- );
2356
- return {
2357
- ...options,
2358
- logging: logging_exports.createLogger(options?.logging),
2359
- headers
2360
- };
2361
- }
2362
- function normalizeClientOptionsWithAuth(options) {
2363
- const normalized = normalizeClientOptions(options);
2364
- if (options.auth === false) {
2365
- normalized.authProvider = new NoOpAuthProvider();
2366
- return normalized;
3021
+ createRun(request, requestOptions) {
3022
+ return HttpResponsePromise.fromPromise(this.__createRun(request, requestOptions));
2367
3023
  }
2368
- if (options.auth != null) {
2369
- if (typeof options.auth === "function") {
2370
- normalized.authProvider = { getAuthRequest: options.auth };
2371
- return normalized;
3024
+ async __createRun(request, requestOptions) {
3025
+ const { "Idempotency-Key": idempotencyKey, ..._body } = request;
3026
+ const _authRequest = await this._options.authProvider.getAuthRequest();
3027
+ const _headers = mergeHeaders(
3028
+ _authRequest.headers,
3029
+ this._options?.headers,
3030
+ mergeOnlyDefinedHeaders({ "Idempotency-Key": idempotencyKey }),
3031
+ requestOptions?.headers
3032
+ );
3033
+ const _response = await fetcher({
3034
+ url: url_exports.join(
3035
+ await Supplier.get(this._options.baseUrl) ?? await Supplier.get(this._options.environment),
3036
+ "v1/runs"
3037
+ ),
3038
+ method: "POST",
3039
+ headers: _headers,
3040
+ contentType: "application/json",
3041
+ queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
3042
+ requestType: "json",
3043
+ body: _body,
3044
+ responseType: "sse",
3045
+ timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
3046
+ maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
3047
+ abortSignal: requestOptions?.abortSignal,
3048
+ fetchFn: this._options?.fetch,
3049
+ logging: this._options.logging
3050
+ });
3051
+ if (_response.ok) {
3052
+ return {
3053
+ data: new Stream({
3054
+ stream: _response.body,
3055
+ parse: (data) => data,
3056
+ signal: requestOptions?.abortSignal,
3057
+ eventShape: {
3058
+ type: "sse"
3059
+ }
3060
+ }),
3061
+ rawResponse: _response.rawResponse
3062
+ };
2372
3063
  }
2373
- if (isAuthProvider(options.auth)) {
2374
- normalized.authProvider = options.auth;
2375
- return normalized;
3064
+ if (_response.error.reason === "status-code") {
3065
+ switch (_response.error.statusCode) {
3066
+ case 400:
3067
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
3068
+ case 401:
3069
+ throw new UnauthorizedError(_response.error.body, _response.rawResponse);
3070
+ case 402:
3071
+ throw new PaymentRequiredError(_response.error.body, _response.rawResponse);
3072
+ case 403:
3073
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
3074
+ case 404:
3075
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
3076
+ case 409:
3077
+ throw new ConflictError(_response.error.body, _response.rawResponse);
3078
+ case 413:
3079
+ throw new ContentTooLargeError(_response.error.body, _response.rawResponse);
3080
+ case 422:
3081
+ throw new UnprocessableEntityError(_response.error.body, _response.rawResponse);
3082
+ case 429:
3083
+ throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
3084
+ case 503:
3085
+ throw new ServiceUnavailableError(_response.error.body, _response.rawResponse);
3086
+ default:
3087
+ throw new VectrosError({
3088
+ statusCode: _response.error.statusCode,
3089
+ body: _response.error.body,
3090
+ rawResponse: _response.rawResponse
3091
+ });
3092
+ }
2376
3093
  }
2377
- Object.assign(normalized, options.auth);
2378
- }
2379
- const normalizedWithNoOpAuthProvider = withNoOpAuthProvider(normalized);
2380
- normalized.authProvider ?? (normalized.authProvider = new BearerAuthProvider(normalizedWithNoOpAuthProvider));
2381
- return normalized;
2382
- }
2383
- function withNoOpAuthProvider(options) {
2384
- return {
2385
- ...options,
2386
- authProvider: new NoOpAuthProvider()
2387
- };
2388
- }
2389
- function handleNonStatusCodeError(error, rawResponse, method, path) {
2390
- switch (error.reason) {
2391
- case "non-json":
2392
- throw new VectrosError({
2393
- statusCode: error.statusCode,
2394
- body: error.rawBody,
2395
- rawResponse
2396
- });
2397
- case "body-is-null":
2398
- throw new VectrosError({
2399
- statusCode: error.statusCode,
2400
- rawResponse
2401
- });
2402
- case "timeout":
2403
- throw new VectrosTimeoutError(`Timeout exceeded when calling ${method} ${path}.`, {
2404
- cause: error.cause
2405
- });
2406
- case "unknown":
2407
- throw new VectrosError({
2408
- message: error.errorMessage,
2409
- rawResponse,
2410
- cause: error.cause
2411
- });
2412
- default:
2413
- throw new VectrosError({
2414
- message: "Unknown error",
2415
- rawResponse
2416
- });
3094
+ return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/runs");
2417
3095
  }
2418
- }
3096
+ };
2419
3097
  var AuthClient = class {
2420
3098
  constructor(options) {
2421
3099
  this._options = normalizeClientOptionsWithAuth(options);
@@ -2614,7 +3292,7 @@ var AuthClient = class {
2614
3292
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/admin/keys/scoped");
2615
3293
  }
2616
3294
  /**
2617
- * 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.
3295
+ * 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.
2618
3296
  *
2619
3297
  * @param {Vectros.CreateScopedKeyRequest} request
2620
3298
  * @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -2957,14 +3635,13 @@ var AuthClient = class {
2957
3635
  * @throws {@link Vectros.BadRequestError}
2958
3636
  * @throws {@link Vectros.ForbiddenError}
2959
3637
  * @throws {@link Vectros.NotFoundError}
3638
+ * @throws {@link Vectros.ConflictError}
2960
3639
  * @throws {@link Vectros.TooManyRequestsError}
2961
3640
  *
2962
3641
  * @example
2963
3642
  * await client.auth.createAccessProfile({
2964
3643
  * contextId: "contextId",
2965
- * body: {
2966
- * principalId: "usr_6ba7b810-9dad-11d1-80b4-00c04fd430c8"
2967
- * }
3644
+ * body: {}
2968
3645
  * })
2969
3646
  */
2970
3647
  createAccessProfile(request, requestOptions) {
@@ -3009,6 +3686,8 @@ var AuthClient = class {
3009
3686
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
3010
3687
  case 404:
3011
3688
  throw new NotFoundError(_response.error.body, _response.rawResponse);
3689
+ case 409:
3690
+ throw new ConflictError(_response.error.body, _response.rawResponse);
3012
3691
  case 429:
3013
3692
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
3014
3693
  default:
@@ -3092,14 +3771,13 @@ var AuthClient = class {
3092
3771
  * @throws {@link Vectros.BadRequestError}
3093
3772
  * @throws {@link Vectros.PaymentRequiredError}
3094
3773
  * @throws {@link Vectros.ForbiddenError}
3774
+ * @throws {@link Vectros.NotFoundError}
3775
+ * @throws {@link Vectros.ConflictError}
3095
3776
  * @throws {@link Vectros.TooManyRequestsError}
3096
3777
  *
3097
3778
  * @example
3098
3779
  * await client.auth.createAppContext({
3099
- * body: {
3100
- * contextId: "myapp",
3101
- * name: "My Internal App"
3102
- * }
3780
+ * body: {}
3103
3781
  * })
3104
3782
  */
3105
3783
  createAppContext(request, requestOptions) {
@@ -3144,6 +3822,10 @@ var AuthClient = class {
3144
3822
  throw new PaymentRequiredError(_response.error.body, _response.rawResponse);
3145
3823
  case 403:
3146
3824
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
3825
+ case 404:
3826
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
3827
+ case 409:
3828
+ throw new ConflictError(_response.error.body, _response.rawResponse);
3147
3829
  case 429:
3148
3830
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
3149
3831
  default:
@@ -3232,18 +3914,13 @@ var AuthClient = class {
3232
3914
  * @throws {@link Vectros.BadRequestError}
3233
3915
  * @throws {@link Vectros.ForbiddenError}
3234
3916
  * @throws {@link Vectros.NotFoundError}
3917
+ * @throws {@link Vectros.ConflictError}
3235
3918
  * @throws {@link Vectros.TooManyRequestsError}
3236
3919
  *
3237
3920
  * @example
3238
3921
  * await client.auth.createRole({
3239
3922
  * contextId: "contextId",
3240
- * body: {
3241
- * roleId: "engineering-member",
3242
- * name: "Engineering Team Member",
3243
- * scopes: [{
3244
- * allowed_actions: ["records:cru", "search:r"]
3245
- * }]
3246
- * }
3923
+ * body: {}
3247
3924
  * })
3248
3925
  */
3249
3926
  createRole(request, requestOptions) {
@@ -3288,6 +3965,8 @@ var AuthClient = class {
3288
3965
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
3289
3966
  case 404:
3290
3967
  throw new NotFoundError(_response.error.body, _response.rawResponse);
3968
+ case 409:
3969
+ throw new ConflictError(_response.error.body, _response.rawResponse);
3291
3970
  case 429:
3292
3971
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
3293
3972
  default:
@@ -3378,15 +4057,14 @@ var AuthClient = class {
3378
4057
  * @throws {@link Vectros.BadRequestError}
3379
4058
  * @throws {@link Vectros.ForbiddenError}
3380
4059
  * @throws {@link Vectros.NotFoundError}
4060
+ * @throws {@link Vectros.ConflictError}
3381
4061
  * @throws {@link Vectros.TooManyRequestsError}
3382
4062
  *
3383
4063
  * @example
3384
4064
  * await client.auth.updateAccessProfile({
3385
4065
  * contextId: "contextId",
3386
4066
  * principalId: "principalId",
3387
- * body: {
3388
- * principalId: "usr_6ba7b810-9dad-11d1-80b4-00c04fd430c8"
3389
- * }
4067
+ * body: {}
3390
4068
  * })
3391
4069
  */
3392
4070
  updateAccessProfile(request, requestOptions) {
@@ -3428,6 +4106,8 @@ var AuthClient = class {
3428
4106
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
3429
4107
  case 404:
3430
4108
  throw new NotFoundError(_response.error.body, _response.rawResponse);
4109
+ case 409:
4110
+ throw new ConflictError(_response.error.body, _response.rawResponse);
3431
4111
  case 429:
3432
4112
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
3433
4113
  default:
@@ -3574,22 +4254,20 @@ var AuthClient = class {
3574
4254
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/app-contexts/{contextId}");
3575
4255
  }
3576
4256
  /**
3577
- * 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.
4257
+ * 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.
3578
4258
  *
3579
4259
  * @param {Vectros.UpdateAppContextRequest} request
3580
4260
  * @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
3581
4261
  *
3582
4262
  * @throws {@link Vectros.ForbiddenError}
3583
4263
  * @throws {@link Vectros.NotFoundError}
4264
+ * @throws {@link Vectros.ConflictError}
3584
4265
  * @throws {@link Vectros.TooManyRequestsError}
3585
4266
  *
3586
4267
  * @example
3587
4268
  * await client.auth.updateAppContext({
3588
4269
  * contextId: "contextId",
3589
- * body: {
3590
- * contextId: "myapp",
3591
- * name: "My Internal App"
3592
- * }
4270
+ * body: {}
3593
4271
  * })
3594
4272
  */
3595
4273
  updateAppContext(request, requestOptions) {
@@ -3629,6 +4307,8 @@ var AuthClient = class {
3629
4307
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
3630
4308
  case 404:
3631
4309
  throw new NotFoundError(_response.error.body, _response.rawResponse);
4310
+ case 409:
4311
+ throw new ConflictError(_response.error.body, _response.rawResponse);
3632
4312
  case 429:
3633
4313
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
3634
4314
  default:
@@ -3785,19 +4465,14 @@ var AuthClient = class {
3785
4465
  *
3786
4466
  * @throws {@link Vectros.ForbiddenError}
3787
4467
  * @throws {@link Vectros.NotFoundError}
4468
+ * @throws {@link Vectros.ConflictError}
3788
4469
  * @throws {@link Vectros.TooManyRequestsError}
3789
4470
  *
3790
4471
  * @example
3791
4472
  * await client.auth.updateRole({
3792
4473
  * contextId: "contextId",
3793
4474
  * roleId: "roleId",
3794
- * body: {
3795
- * roleId: "engineering-member",
3796
- * name: "Engineering Team Member",
3797
- * scopes: [{
3798
- * allowed_actions: ["records:cru", "search:r"]
3799
- * }]
3800
- * }
4475
+ * body: {}
3801
4476
  * })
3802
4477
  */
3803
4478
  updateRole(request, requestOptions) {
@@ -3837,6 +4512,8 @@ var AuthClient = class {
3837
4512
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
3838
4513
  case 404:
3839
4514
  throw new NotFoundError(_response.error.body, _response.rawResponse);
4515
+ case 409:
4516
+ throw new ConflictError(_response.error.body, _response.rawResponse);
3840
4517
  case 429:
3841
4518
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
3842
4519
  default:
@@ -3862,6 +4539,7 @@ var AuthClient = class {
3862
4539
  *
3863
4540
  * @throws {@link Vectros.ForbiddenError}
3864
4541
  * @throws {@link Vectros.NotFoundError}
4542
+ * @throws {@link Vectros.ConflictError}
3865
4543
  * @throws {@link Vectros.TooManyRequestsError}
3866
4544
  *
3867
4545
  * @example
@@ -3904,6 +4582,8 @@ var AuthClient = class {
3904
4582
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
3905
4583
  case 404:
3906
4584
  throw new NotFoundError(_response.error.body, _response.rawResponse);
4585
+ case 409:
4586
+ throw new ConflictError(_response.error.body, _response.rawResponse);
3907
4587
  case 429:
3908
4588
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
3909
4589
  default:
@@ -4185,6 +4865,7 @@ var AuthClient = class {
4185
4865
  * @throws {@link Vectros.BadRequestError}
4186
4866
  * @throws {@link Vectros.ForbiddenError}
4187
4867
  * @throws {@link Vectros.NotFoundError}
4868
+ * @throws {@link Vectros.ConflictError}
4188
4869
  * @throws {@link Vectros.TooManyRequestsError}
4189
4870
  *
4190
4871
  * @example
@@ -4231,6 +4912,8 @@ var AuthClient = class {
4231
4912
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
4232
4913
  case 404:
4233
4914
  throw new NotFoundError(_response.error.body, _response.rawResponse);
4915
+ case 409:
4916
+ throw new ConflictError(_response.error.body, _response.rawResponse);
4234
4917
  case 429:
4235
4918
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
4236
4919
  default:
@@ -4244,7 +4927,7 @@ var AuthClient = class {
4244
4927
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "PUT", "/v1/auth/issuers/{issuerId}");
4245
4928
  }
4246
4929
  /**
4247
- * 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.
4930
+ * 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.
4248
4931
  *
4249
4932
  * @param {Vectros.DeleteIssuerRequest} request
4250
4933
  * @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -4370,7 +5053,7 @@ var AuthClient = class {
4370
5053
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/auth/issuers");
4371
5054
  }
4372
5055
  /**
4373
- * 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.
5056
+ * 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.
4374
5057
  *
4375
5058
  * @param {Vectros.IssuerRequest} request
4376
5059
  * @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -4779,6 +5462,7 @@ var AuthClient = class {
4779
5462
  * @throws {@link Vectros.BadRequestError}
4780
5463
  * @throws {@link Vectros.ForbiddenError}
4781
5464
  * @throws {@link Vectros.NotFoundError}
5465
+ * @throws {@link Vectros.ConflictError}
4782
5466
  * @throws {@link Vectros.TooManyRequestsError}
4783
5467
  *
4784
5468
  * @example
@@ -4826,6 +5510,8 @@ var AuthClient = class {
4826
5510
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
4827
5511
  case 404:
4828
5512
  throw new NotFoundError(_response.error.body, _response.rawResponse);
5513
+ case 409:
5514
+ throw new ConflictError(_response.error.body, _response.rawResponse);
4829
5515
  case 429:
4830
5516
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
4831
5517
  default:
@@ -4925,6 +5611,7 @@ var AuthClient = class {
4925
5611
  * @throws {@link Vectros.UnauthorizedError}
4926
5612
  * @throws {@link Vectros.ForbiddenError}
4927
5613
  * @throws {@link Vectros.NotFoundError}
5614
+ * @throws {@link Vectros.ContentTooLargeError}
4928
5615
  * @throws {@link Vectros.TooManyRequestsError}
4929
5616
  *
4930
5617
  * @example
@@ -4969,6 +5656,8 @@ var AuthClient = class {
4969
5656
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
4970
5657
  case 404:
4971
5658
  throw new NotFoundError(_response.error.body, _response.rawResponse);
5659
+ case 413:
5660
+ throw new ContentTooLargeError(_response.error.body, _response.rawResponse);
4972
5661
  case 429:
4973
5662
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
4974
5663
  default:
@@ -5108,7 +5797,7 @@ var ComplianceClient = class {
5108
5797
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/erasure-requests/{id}");
5109
5798
  }
5110
5799
  /**
5111
- * 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.
5800
+ * 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.
5112
5801
  *
5113
5802
  * @param {Vectros.ExportRequest} request
5114
5803
  * @param {ComplianceClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -5169,7 +5858,7 @@ var ComplianceClient = class {
5169
5858
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/admin/export");
5170
5859
  }
5171
5860
  /**
5172
- * 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.
5861
+ * 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.
5173
5862
  *
5174
5863
  * @param {Vectros.GetExportRequest} request
5175
5864
  * @param {ComplianceClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -5235,7 +5924,7 @@ var DocumentsClient = class {
5235
5924
  this._options = normalizeClientOptionsWithAuth(options);
5236
5925
  }
5237
5926
  /**
5238
- * 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.
5927
+ * 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.
5239
5928
  *
5240
5929
  * @param {Vectros.ListDocumentsRequest} request
5241
5930
  * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -5245,6 +5934,7 @@ var DocumentsClient = class {
5245
5934
  * userId: "550e8400-e29b-41d4-a716-446655440000",
5246
5935
  * scope: "group:eng-team",
5247
5936
  * folderId: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
5937
+ * type: "investigation_report",
5248
5938
  * startFrom: "b3BhcXVlLWN1cnNvci1mcm9tLXRoZS1wcmV2aW91cy1wYWdl"
5249
5939
  * })
5250
5940
  */
@@ -5252,11 +5942,12 @@ var DocumentsClient = class {
5252
5942
  return HttpResponsePromise.fromPromise(this.__listDocuments(request, requestOptions));
5253
5943
  }
5254
5944
  async __listDocuments(request = {}, requestOptions) {
5255
- const { userId, scope, folderId, startFrom, limit } = request;
5945
+ const { userId, scope, folderId, type: type_, startFrom, limit } = request;
5256
5946
  const _queryParams = {
5257
5947
  userId,
5258
5948
  scope,
5259
5949
  folderId,
5950
+ type: type_,
5260
5951
  startFrom,
5261
5952
  limit
5262
5953
  };
@@ -5300,13 +5991,13 @@ var DocumentsClient = class {
5300
5991
  *
5301
5992
  * @throws {@link Vectros.BadRequestError}
5302
5993
  * @throws {@link Vectros.ForbiddenError}
5994
+ * @throws {@link Vectros.NotFoundError}
5995
+ * @throws {@link Vectros.ConflictError}
5303
5996
  * @throws {@link Vectros.TooManyRequestsError}
5304
5997
  *
5305
5998
  * @example
5306
5999
  * await client.documents.ingestDocument({
5307
- * body: {
5308
- * title: "Patient Intake Form \u2014 Jane Doe"
5309
- * }
6000
+ * body: {}
5310
6001
  * })
5311
6002
  */
5312
6003
  ingestDocument(request, requestOptions) {
@@ -5351,6 +6042,10 @@ var DocumentsClient = class {
5351
6042
  throw new BadRequestError(_response.error.body, _response.rawResponse);
5352
6043
  case 403:
5353
6044
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
6045
+ case 404:
6046
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
6047
+ case 409:
6048
+ throw new ConflictError(_response.error.body, _response.rawResponse);
5354
6049
  case 429:
5355
6050
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
5356
6051
  default:
@@ -5432,9 +6127,7 @@ var DocumentsClient = class {
5432
6127
  * @example
5433
6128
  * await client.documents.updateDocument({
5434
6129
  * id: "id",
5435
- * body: {
5436
- * title: "Patient Intake Form \u2014 Jane Doe"
5437
- * }
6130
+ * body: {}
5438
6131
  * })
5439
6132
  */
5440
6133
  updateDocument(request, requestOptions) {
@@ -5498,6 +6191,7 @@ var DocumentsClient = class {
5498
6191
  * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
5499
6192
  *
5500
6193
  * @throws {@link Vectros.NotFoundError}
6194
+ * @throws {@link Vectros.ConflictError}
5501
6195
  * @throws {@link Vectros.TooManyRequestsError}
5502
6196
  *
5503
6197
  * @example
@@ -5537,6 +6231,8 @@ var DocumentsClient = class {
5537
6231
  switch (_response.error.statusCode) {
5538
6232
  case 404:
5539
6233
  throw new NotFoundError(_response.error.body, _response.rawResponse);
6234
+ case 409:
6235
+ throw new ConflictError(_response.error.body, _response.rawResponse);
5540
6236
  case 429:
5541
6237
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
5542
6238
  default:
@@ -5829,11 +6525,12 @@ var DocumentsClient = class {
5829
6525
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/documents/{id}/download");
5830
6526
  }
5831
6527
  /**
5832
- * 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.
6528
+ * 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.
5833
6529
  *
5834
6530
  * @param {Vectros.GetDocumentTextRequest} request
5835
6531
  * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
5836
6532
  *
6533
+ * @throws {@link Vectros.BadRequestError}
5837
6534
  * @throws {@link Vectros.NotFoundError}
5838
6535
  *
5839
6536
  * @example
@@ -5845,7 +6542,11 @@ var DocumentsClient = class {
5845
6542
  return HttpResponsePromise.fromPromise(this.__getDocumentText(request, requestOptions));
5846
6543
  }
5847
6544
  async __getDocumentText(request, requestOptions) {
5848
- const { id } = request;
6545
+ const { id, offset, limit } = request;
6546
+ const _queryParams = {
6547
+ offset,
6548
+ limit
6549
+ };
5849
6550
  const _authRequest = await this._options.authProvider.getAuthRequest();
5850
6551
  const _headers = mergeHeaders(
5851
6552
  _authRequest.headers,
@@ -5859,7 +6560,7 @@ var DocumentsClient = class {
5859
6560
  ),
5860
6561
  method: "GET",
5861
6562
  headers: _headers,
5862
- queryString: url_exports.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(),
6563
+ queryString: url_exports.queryBuilder().addMany(_queryParams).mergeAdditional(requestOptions?.queryParams).build(),
5863
6564
  timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1e3,
5864
6565
  maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries,
5865
6566
  abortSignal: requestOptions?.abortSignal,
@@ -5871,6 +6572,8 @@ var DocumentsClient = class {
5871
6572
  }
5872
6573
  if (_response.error.reason === "status-code") {
5873
6574
  switch (_response.error.statusCode) {
6575
+ case 400:
6576
+ throw new BadRequestError(_response.error.body, _response.rawResponse);
5874
6577
  case 404:
5875
6578
  throw new NotFoundError(_response.error.body, _response.rawResponse);
5876
6579
  default:
@@ -5949,6 +6652,7 @@ var DocumentsClient = class {
5949
6652
  *
5950
6653
  * @throws {@link Vectros.BadRequestError}
5951
6654
  * @throws {@link Vectros.ForbiddenError}
6655
+ * @throws {@link Vectros.ConflictError}
5952
6656
  * @throws {@link Vectros.TooManyRequestsError}
5953
6657
  *
5954
6658
  * @example
@@ -5998,6 +6702,8 @@ var DocumentsClient = class {
5998
6702
  throw new BadRequestError(_response.error.body, _response.rawResponse);
5999
6703
  case 403:
6000
6704
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
6705
+ case 409:
6706
+ throw new ConflictError(_response.error.body, _response.rawResponse);
6001
6707
  case 429:
6002
6708
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
6003
6709
  default:
@@ -6081,13 +6787,13 @@ var FoldersClient = class {
6081
6787
  *
6082
6788
  * @throws {@link Vectros.BadRequestError}
6083
6789
  * @throws {@link Vectros.ForbiddenError}
6790
+ * @throws {@link Vectros.NotFoundError}
6791
+ * @throws {@link Vectros.ConflictError}
6084
6792
  * @throws {@link Vectros.TooManyRequestsError}
6085
6793
  *
6086
6794
  * @example
6087
6795
  * await client.folders.createFolder({
6088
- * body: {
6089
- * name: "Patient Records 2024"
6090
- * }
6796
+ * body: {}
6091
6797
  * })
6092
6798
  */
6093
6799
  createFolder(request, requestOptions) {
@@ -6130,6 +6836,10 @@ var FoldersClient = class {
6130
6836
  throw new BadRequestError(_response.error.body, _response.rawResponse);
6131
6837
  case 403:
6132
6838
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
6839
+ case 404:
6840
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
6841
+ case 409:
6842
+ throw new ConflictError(_response.error.body, _response.rawResponse);
6133
6843
  case 429:
6134
6844
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
6135
6845
  default:
@@ -6205,14 +6915,13 @@ var FoldersClient = class {
6205
6915
  *
6206
6916
  * @throws {@link Vectros.ForbiddenError}
6207
6917
  * @throws {@link Vectros.NotFoundError}
6918
+ * @throws {@link Vectros.ConflictError}
6208
6919
  * @throws {@link Vectros.TooManyRequestsError}
6209
6920
  *
6210
6921
  * @example
6211
6922
  * await client.folders.updateFolder({
6212
6923
  * id: "id",
6213
- * body: {
6214
- * name: "Patient Records 2024"
6215
- * }
6924
+ * body: {}
6216
6925
  * })
6217
6926
  */
6218
6927
  updateFolder(request, requestOptions) {
@@ -6252,6 +6961,8 @@ var FoldersClient = class {
6252
6961
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
6253
6962
  case 404:
6254
6963
  throw new NotFoundError(_response.error.body, _response.rawResponse);
6964
+ case 409:
6965
+ throw new ConflictError(_response.error.body, _response.rawResponse);
6255
6966
  case 429:
6256
6967
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
6257
6968
  default:
@@ -6272,6 +6983,7 @@ var FoldersClient = class {
6272
6983
  *
6273
6984
  * @throws {@link Vectros.BadRequestError}
6274
6985
  * @throws {@link Vectros.NotFoundError}
6986
+ * @throws {@link Vectros.ConflictError}
6275
6987
  * @throws {@link Vectros.TooManyRequestsError}
6276
6988
  *
6277
6989
  * @example
@@ -6313,6 +7025,8 @@ var FoldersClient = class {
6313
7025
  throw new BadRequestError(_response.error.body, _response.rawResponse);
6314
7026
  case 404:
6315
7027
  throw new NotFoundError(_response.error.body, _response.rawResponse);
7028
+ case 409:
7029
+ throw new ConflictError(_response.error.body, _response.rawResponse);
6316
7030
  case 429:
6317
7031
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
6318
7032
  default:
@@ -6326,7 +7040,7 @@ var FoldersClient = class {
6326
7040
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "DELETE", "/v1/folders/{id}");
6327
7041
  }
6328
7042
  /**
6329
- * 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.
7043
+ * 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.
6330
7044
  *
6331
7045
  * @param {Vectros.PatchFolderRequest} request
6332
7046
  * @param {FoldersClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -6340,9 +7054,7 @@ var FoldersClient = class {
6340
7054
  * @example
6341
7055
  * await client.folders.patchFolder({
6342
7056
  * id: "id",
6343
- * body: {
6344
- * name: "Patient Records 2024"
6345
- * }
7057
+ * body: {}
6346
7058
  * })
6347
7059
  */
6348
7060
  patchFolder(request, requestOptions) {
@@ -6549,15 +7261,15 @@ var IdentityClient = class {
6549
7261
  *
6550
7262
  * @throws {@link Vectros.BadRequestError}
6551
7263
  * @throws {@link Vectros.ForbiddenError}
7264
+ * @throws {@link Vectros.NotFoundError}
7265
+ * @throws {@link Vectros.ConflictError}
6552
7266
  * @throws {@link Vectros.TooManyRequestsError}
6553
7267
  *
6554
7268
  * @example
6555
7269
  * await client.identity.createEntity({
6556
7270
  * namespace: "team",
6557
7271
  * contextId: "myapp",
6558
- * body: {
6559
- * externalId: "team_eng_platform"
6560
- * }
7272
+ * body: {}
6561
7273
  * })
6562
7274
  */
6563
7275
  createEntity(request, requestOptions) {
@@ -6601,6 +7313,10 @@ var IdentityClient = class {
6601
7313
  throw new BadRequestError(_response.error.body, _response.rawResponse);
6602
7314
  case 403:
6603
7315
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
7316
+ case 404:
7317
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
7318
+ case 409:
7319
+ throw new ConflictError(_response.error.body, _response.rawResponse);
6604
7320
  case 429:
6605
7321
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
6606
7322
  default:
@@ -6681,6 +7397,7 @@ var IdentityClient = class {
6681
7397
  *
6682
7398
  * @throws {@link Vectros.BadRequestError}
6683
7399
  * @throws {@link Vectros.NotFoundError}
7400
+ * @throws {@link Vectros.ConflictError}
6684
7401
  * @throws {@link Vectros.TooManyRequestsError}
6685
7402
  *
6686
7403
  * @example
@@ -6688,9 +7405,7 @@ var IdentityClient = class {
6688
7405
  * namespace: "team",
6689
7406
  * id: "id",
6690
7407
  * contextId: "myapp",
6691
- * body: {
6692
- * externalId: "team_eng_platform"
6693
- * }
7408
+ * body: {}
6694
7409
  * })
6695
7410
  */
6696
7411
  updateEntity(request, requestOptions) {
@@ -6733,6 +7448,8 @@ var IdentityClient = class {
6733
7448
  throw new BadRequestError(_response.error.body, _response.rawResponse);
6734
7449
  case 404:
6735
7450
  throw new NotFoundError(_response.error.body, _response.rawResponse);
7451
+ case 409:
7452
+ throw new ConflictError(_response.error.body, _response.rawResponse);
6736
7453
  case 429:
6737
7454
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
6738
7455
  default:
@@ -6752,6 +7469,7 @@ var IdentityClient = class {
6752
7469
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
6753
7470
  *
6754
7471
  * @throws {@link Vectros.NotFoundError}
7472
+ * @throws {@link Vectros.ConflictError}
6755
7473
  * @throws {@link Vectros.TooManyRequestsError}
6756
7474
  *
6757
7475
  * @example
@@ -6796,6 +7514,8 @@ var IdentityClient = class {
6796
7514
  switch (_response.error.statusCode) {
6797
7515
  case 404:
6798
7516
  throw new NotFoundError(_response.error.body, _response.rawResponse);
7517
+ case 409:
7518
+ throw new ConflictError(_response.error.body, _response.rawResponse);
6799
7519
  case 429:
6800
7520
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
6801
7521
  default:
@@ -7019,15 +7739,13 @@ var IdentityClient = class {
7019
7739
  *
7020
7740
  * @throws {@link Vectros.ForbiddenError}
7021
7741
  * @throws {@link Vectros.NotFoundError}
7742
+ * @throws {@link Vectros.ConflictError}
7022
7743
  * @throws {@link Vectros.TooManyRequestsError}
7023
7744
  *
7024
7745
  * @example
7025
7746
  * await client.identity.updateNamespace({
7026
7747
  * namespace: "team",
7027
- * body: {
7028
- * namespace: "team",
7029
- * specificityRank: 1500
7030
- * }
7748
+ * body: {}
7031
7749
  * })
7032
7750
  */
7033
7751
  updateNamespace(request, requestOptions) {
@@ -7070,6 +7788,8 @@ var IdentityClient = class {
7070
7788
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
7071
7789
  case 404:
7072
7790
  throw new NotFoundError(_response.error.body, _response.rawResponse);
7791
+ case 409:
7792
+ throw new ConflictError(_response.error.body, _response.rawResponse);
7073
7793
  case 429:
7074
7794
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
7075
7795
  default:
@@ -7090,6 +7810,7 @@ var IdentityClient = class {
7090
7810
  *
7091
7811
  * @throws {@link Vectros.ForbiddenError}
7092
7812
  * @throws {@link Vectros.NotFoundError}
7813
+ * @throws {@link Vectros.ConflictError}
7093
7814
  * @throws {@link Vectros.TooManyRequestsError}
7094
7815
  *
7095
7816
  * @example
@@ -7134,6 +7855,8 @@ var IdentityClient = class {
7134
7855
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
7135
7856
  case 404:
7136
7857
  throw new NotFoundError(_response.error.body, _response.rawResponse);
7858
+ case 409:
7859
+ throw new ConflictError(_response.error.body, _response.rawResponse);
7137
7860
  case 429:
7138
7861
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
7139
7862
  default:
@@ -7198,7 +7921,7 @@ var IdentityClient = class {
7198
7921
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/namespaces");
7199
7922
  }
7200
7923
  /**
7201
- * 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.
7924
+ * 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.
7202
7925
  *
7203
7926
  * @param {Vectros.RegisterNamespaceRequest} request
7204
7927
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -7209,10 +7932,7 @@ var IdentityClient = class {
7209
7932
  *
7210
7933
  * @example
7211
7934
  * await client.identity.registerNamespace({
7212
- * body: {
7213
- * namespace: "team",
7214
- * specificityRank: 1500
7215
- * }
7935
+ * body: {}
7216
7936
  * })
7217
7937
  */
7218
7938
  registerNamespace(request, requestOptions) {
@@ -7340,13 +8060,12 @@ var IdentityClient = class {
7340
8060
  *
7341
8061
  * @throws {@link Vectros.BadRequestError}
7342
8062
  * @throws {@link Vectros.ForbiddenError}
8063
+ * @throws {@link Vectros.ConflictError}
7343
8064
  * @throws {@link Vectros.TooManyRequestsError}
7344
8065
  *
7345
8066
  * @example
7346
8067
  * await client.identity.createUser({
7347
- * body: {
7348
- * externalId: "usr_12345"
7349
- * }
8068
+ * body: {}
7350
8069
  * })
7351
8070
  */
7352
8071
  createUser(request, requestOptions) {
@@ -7389,6 +8108,8 @@ var IdentityClient = class {
7389
8108
  throw new BadRequestError(_response.error.body, _response.rawResponse);
7390
8109
  case 403:
7391
8110
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
8111
+ case 409:
8112
+ throw new ConflictError(_response.error.body, _response.rawResponse);
7392
8113
  case 429:
7393
8114
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
7394
8115
  default:
@@ -7457,21 +8178,21 @@ var IdentityClient = class {
7457
8178
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/users/{id}");
7458
8179
  }
7459
8180
  /**
7460
- * 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.
8181
+ * 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.
7461
8182
  *
7462
8183
  * @param {Vectros.UpdateUserRequest} request
7463
8184
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
7464
8185
  *
7465
8186
  * @throws {@link Vectros.BadRequestError}
8187
+ * @throws {@link Vectros.ForbiddenError}
7466
8188
  * @throws {@link Vectros.NotFoundError}
8189
+ * @throws {@link Vectros.ConflictError}
7467
8190
  * @throws {@link Vectros.TooManyRequestsError}
7468
8191
  *
7469
8192
  * @example
7470
8193
  * await client.identity.updateUser({
7471
8194
  * id: "550e8400-e29b-41d4-a716-446655440000",
7472
- * body: {
7473
- * externalId: "usr_12345"
7474
- * }
8195
+ * body: {}
7475
8196
  * })
7476
8197
  */
7477
8198
  updateUser(request, requestOptions) {
@@ -7509,8 +8230,12 @@ var IdentityClient = class {
7509
8230
  switch (_response.error.statusCode) {
7510
8231
  case 400:
7511
8232
  throw new BadRequestError(_response.error.body, _response.rawResponse);
8233
+ case 403:
8234
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
7512
8235
  case 404:
7513
8236
  throw new NotFoundError(_response.error.body, _response.rawResponse);
8237
+ case 409:
8238
+ throw new ConflictError(_response.error.body, _response.rawResponse);
7514
8239
  case 429:
7515
8240
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
7516
8241
  default:
@@ -7529,6 +8254,7 @@ var IdentityClient = class {
7529
8254
  * @param {Vectros.DeleteUserRequest} request
7530
8255
  * @param {IdentityClient.RequestOptions} requestOptions - Request-specific configuration.
7531
8256
  *
8257
+ * @throws {@link Vectros.ForbiddenError}
7532
8258
  * @throws {@link Vectros.NotFoundError}
7533
8259
  * @throws {@link Vectros.ConflictError}
7534
8260
  * @throws {@link Vectros.TooManyRequestsError}
@@ -7568,6 +8294,8 @@ var IdentityClient = class {
7568
8294
  }
7569
8295
  if (_response.error.reason === "status-code") {
7570
8296
  switch (_response.error.statusCode) {
8297
+ case 403:
8298
+ throw new ForbiddenError(_response.error.body, _response.rawResponse);
7571
8299
  case 404:
7572
8300
  throw new NotFoundError(_response.error.body, _response.rawResponse);
7573
8301
  case 409:
@@ -7772,7 +8500,7 @@ var InferenceClient = class {
7772
8500
  this._options = normalizeClientOptionsWithAuth(options);
7773
8501
  }
7774
8502
  /**
7775
- * 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`.
8503
+ * 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`.
7776
8504
  *
7777
8505
  * @param {InferenceClient.RequestOptions} requestOptions - Request-specific configuration.
7778
8506
  *
@@ -7816,7 +8544,7 @@ var InferenceClient = class {
7816
8544
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/models");
7817
8545
  }
7818
8546
  /**
7819
- * 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.
8547
+ * 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.
7820
8548
  */
7821
8549
  chatInference(request, requestOptions) {
7822
8550
  return HttpResponsePromise.fromPromise(this.__chatInference(request, requestOptions));
@@ -7869,10 +8597,14 @@ var InferenceClient = class {
7869
8597
  throw new PaymentRequiredError(_response.error.body, _response.rawResponse);
7870
8598
  case 403:
7871
8599
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
8600
+ case 404:
8601
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
7872
8602
  case 413:
7873
8603
  throw new ContentTooLargeError(_response.error.body, _response.rawResponse);
7874
8604
  case 429:
7875
8605
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
8606
+ case 503:
8607
+ throw new ServiceUnavailableError(_response.error.body, _response.rawResponse);
7876
8608
  default:
7877
8609
  throw new VectrosError({
7878
8610
  statusCode: _response.error.statusCode,
@@ -7884,7 +8616,7 @@ var InferenceClient = class {
7884
8616
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/chat");
7885
8617
  }
7886
8618
  /**
7887
- * 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.
8619
+ * 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.
7888
8620
  */
7889
8621
  documentAsk(request, requestOptions) {
7890
8622
  return HttpResponsePromise.fromPromise(this.__documentAsk(request, requestOptions));
@@ -7946,6 +8678,8 @@ var InferenceClient = class {
7946
8678
  throw new ContentTooLargeError(_response.error.body, _response.rawResponse);
7947
8679
  case 429:
7948
8680
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
8681
+ case 503:
8682
+ throw new ServiceUnavailableError(_response.error.body, _response.rawResponse);
7949
8683
  default:
7950
8684
  throw new VectrosError({
7951
8685
  statusCode: _response.error.statusCode,
@@ -8010,12 +8744,16 @@ var InferenceClient = class {
8010
8744
  throw new PaymentRequiredError(_response.error.body, _response.rawResponse);
8011
8745
  case 403:
8012
8746
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
8747
+ case 404:
8748
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
8013
8749
  case 413:
8014
8750
  throw new ContentTooLargeError(_response.error.body, _response.rawResponse);
8015
8751
  case 429:
8016
8752
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
8017
8753
  case 500:
8018
8754
  throw new InternalServerError(_response.error.body, _response.rawResponse);
8755
+ case 503:
8756
+ throw new ServiceUnavailableError(_response.error.body, _response.rawResponse);
8019
8757
  default:
8020
8758
  throw new VectrosError({
8021
8759
  statusCode: _response.error.statusCode,
@@ -8093,7 +8831,7 @@ var RecordsClient = class {
8093
8831
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/records/batch-get");
8094
8832
  }
8095
8833
  /**
8096
- * 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.
8834
+ * 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.
8097
8835
  *
8098
8836
  * @param {Vectros.BatchLookupRequest} request
8099
8837
  * @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -8154,7 +8892,7 @@ var RecordsClient = class {
8154
8892
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/records/lookup/batch");
8155
8893
  }
8156
8894
  /**
8157
- * 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.
8895
+ * 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.
8158
8896
  *
8159
8897
  * `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.
8160
8898
  *
@@ -8293,6 +9031,8 @@ var RecordsClient = class {
8293
9031
  *
8294
9032
  * @throws {@link Vectros.BadRequestError}
8295
9033
  * @throws {@link Vectros.ForbiddenError}
9034
+ * @throws {@link Vectros.NotFoundError}
9035
+ * @throws {@link Vectros.ConflictError}
8296
9036
  * @throws {@link Vectros.TooManyRequestsError}
8297
9037
  *
8298
9038
  * @example
@@ -8349,6 +9089,10 @@ var RecordsClient = class {
8349
9089
  throw new BadRequestError(_response.error.body, _response.rawResponse);
8350
9090
  case 403:
8351
9091
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
9092
+ case 404:
9093
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
9094
+ case 409:
9095
+ throw new ConflictError(_response.error.body, _response.rawResponse);
8352
9096
  case 429:
8353
9097
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
8354
9098
  default:
@@ -8497,6 +9241,7 @@ var RecordsClient = class {
8497
9241
  * @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
8498
9242
  *
8499
9243
  * @throws {@link Vectros.NotFoundError}
9244
+ * @throws {@link Vectros.ConflictError}
8500
9245
  * @throws {@link Vectros.TooManyRequestsError}
8501
9246
  *
8502
9247
  * @example
@@ -8536,6 +9281,8 @@ var RecordsClient = class {
8536
9281
  switch (_response.error.statusCode) {
8537
9282
  case 404:
8538
9283
  throw new NotFoundError(_response.error.body, _response.rawResponse);
9284
+ case 409:
9285
+ throw new ConflictError(_response.error.body, _response.rawResponse);
8539
9286
  case 429:
8540
9287
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
8541
9288
  default:
@@ -8549,7 +9296,7 @@ var RecordsClient = class {
8549
9296
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "DELETE", "/v1/records/{id}");
8550
9297
  }
8551
9298
  /**
8552
- * 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.
9299
+ * 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.
8553
9300
  *
8554
9301
  * @param {Vectros.PatchRecordRequest} request
8555
9302
  * @param {RecordsClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -8978,6 +9725,8 @@ var SchemasClient = class {
8978
9725
  *
8979
9726
  * @throws {@link Vectros.BadRequestError}
8980
9727
  * @throws {@link Vectros.ForbiddenError}
9728
+ * @throws {@link Vectros.NotFoundError}
9729
+ * @throws {@link Vectros.ConflictError}
8981
9730
  * @throws {@link Vectros.TooManyRequestsError}
8982
9731
  *
8983
9732
  * @example
@@ -9002,8 +9751,7 @@ var SchemasClient = class {
9002
9751
  * }],
9003
9752
  * capabilities: {
9004
9753
  * "auditHistory": true
9005
- * },
9006
- * allowedSurfaces: ["record"]
9754
+ * }
9007
9755
  * }
9008
9756
  * })
9009
9757
  */
@@ -9047,6 +9795,10 @@ var SchemasClient = class {
9047
9795
  throw new BadRequestError(_response.error.body, _response.rawResponse);
9048
9796
  case 403:
9049
9797
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
9798
+ case 404:
9799
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
9800
+ case 409:
9801
+ throw new ConflictError(_response.error.body, _response.rawResponse);
9050
9802
  case 429:
9051
9803
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
9052
9804
  default:
@@ -9129,11 +9881,7 @@ var SchemasClient = class {
9129
9881
  * @example
9130
9882
  * await client.schemas.updateSchema({
9131
9883
  * id: "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
9132
- * body: {
9133
- * typeName: "intake_form",
9134
- * displayName: "Client Intake Form",
9135
- * allowedSurfaces: ["record"]
9136
- * }
9884
+ * body: {}
9137
9885
  * })
9138
9886
  */
9139
9887
  updateSchema(request, requestOptions) {
@@ -9190,7 +9938,7 @@ var SchemasClient = class {
9190
9938
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "PUT", "/v1/schemas/{id}");
9191
9939
  }
9192
9940
  /**
9193
- * 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.
9941
+ * 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.
9194
9942
  *
9195
9943
  * @param {Vectros.DeleteSchemaRequest} request
9196
9944
  * @param {SchemasClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -9317,7 +10065,7 @@ var ScriptsClient = class {
9317
10065
  this._options = normalizeClientOptionsWithAuth(options);
9318
10066
  }
9319
10067
  /**
9320
- * 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.
10068
+ * 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.
9321
10069
  *
9322
10070
  * **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.
9323
10071
  *
@@ -9673,7 +10421,7 @@ var ScriptsClient = class {
9673
10421
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "PUT", "/v1/scripts/{id}");
9674
10422
  }
9675
10423
  /**
9676
- * 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.
10424
+ * 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.
9677
10425
  *
9678
10426
  * @param {Vectros.DeleteScriptRequest} request
9679
10427
  * @param {ScriptsClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -9931,21 +10679,13 @@ var TriggersClient = class {
9931
10679
  *
9932
10680
  * @throws {@link Vectros.BadRequestError}
9933
10681
  * @throws {@link Vectros.ForbiddenError}
10682
+ * @throws {@link Vectros.NotFoundError}
10683
+ * @throws {@link Vectros.ConflictError}
9934
10684
  * @throws {@link Vectros.TooManyRequestsError}
9935
10685
  *
9936
10686
  * @example
9937
10687
  * await client.triggers.createTrigger({
9938
- * body: {
9939
- * name: "on-intake-create",
9940
- * firingSource: {
9941
- * schemaId: "sch_9f8e7d6c",
9942
- * event: "CREATE"
9943
- * },
9944
- * scriptRef: {
9945
- * name: "notify-assignee",
9946
- * version: "3"
9947
- * }
9948
- * }
10688
+ * body: {}
9949
10689
  * })
9950
10690
  */
9951
10691
  createTrigger(request, requestOptions) {
@@ -9988,6 +10728,10 @@ var TriggersClient = class {
9988
10728
  throw new BadRequestError(_response.error.body, _response.rawResponse);
9989
10729
  case 403:
9990
10730
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
10731
+ case 404:
10732
+ throw new NotFoundError(_response.error.body, _response.rawResponse);
10733
+ case 409:
10734
+ throw new ConflictError(_response.error.body, _response.rawResponse);
9991
10735
  case 429:
9992
10736
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
9993
10737
  default:
@@ -10064,22 +10808,13 @@ var TriggersClient = class {
10064
10808
  * @throws {@link Vectros.BadRequestError}
10065
10809
  * @throws {@link Vectros.ForbiddenError}
10066
10810
  * @throws {@link Vectros.NotFoundError}
10811
+ * @throws {@link Vectros.ConflictError}
10067
10812
  * @throws {@link Vectros.TooManyRequestsError}
10068
10813
  *
10069
10814
  * @example
10070
10815
  * await client.triggers.updateTrigger({
10071
10816
  * id: "id",
10072
- * body: {
10073
- * name: "on-intake-create",
10074
- * firingSource: {
10075
- * schemaId: "sch_9f8e7d6c",
10076
- * event: "CREATE"
10077
- * },
10078
- * scriptRef: {
10079
- * name: "notify-assignee",
10080
- * version: "3"
10081
- * }
10082
- * }
10817
+ * body: {}
10083
10818
  * })
10084
10819
  */
10085
10820
  updateTrigger(request, requestOptions) {
@@ -10121,6 +10856,8 @@ var TriggersClient = class {
10121
10856
  throw new ForbiddenError(_response.error.body, _response.rawResponse);
10122
10857
  case 404:
10123
10858
  throw new NotFoundError(_response.error.body, _response.rawResponse);
10859
+ case 409:
10860
+ throw new ConflictError(_response.error.body, _response.rawResponse);
10124
10861
  case 429:
10125
10862
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
10126
10863
  default:
@@ -10140,6 +10877,7 @@ var TriggersClient = class {
10140
10877
  * @param {TriggersClient.RequestOptions} requestOptions - Request-specific configuration.
10141
10878
  *
10142
10879
  * @throws {@link Vectros.NotFoundError}
10880
+ * @throws {@link Vectros.ConflictError}
10143
10881
  * @throws {@link Vectros.TooManyRequestsError}
10144
10882
  *
10145
10883
  * @example
@@ -10179,6 +10917,8 @@ var TriggersClient = class {
10179
10917
  switch (_response.error.statusCode) {
10180
10918
  case 404:
10181
10919
  throw new NotFoundError(_response.error.body, _response.rawResponse);
10920
+ case 409:
10921
+ throw new ConflictError(_response.error.body, _response.rawResponse);
10182
10922
  case 429:
10183
10923
  throw new TooManyRequestsError(_response.error.body, _response.rawResponse);
10184
10924
  default:
@@ -10199,6 +10939,9 @@ var VectrosClient = class {
10199
10939
  get auth() {
10200
10940
  return this._auth ?? (this._auth = new AuthClient(this._options));
10201
10941
  }
10942
+ get agents() {
10943
+ return this._agents ?? (this._agents = new AgentsClient(this._options));
10944
+ }
10202
10945
  get documents() {
10203
10946
  return this._documents ?? (this._documents = new DocumentsClient(this._options));
10204
10947
  }
@@ -10264,7 +11007,7 @@ var logging;
10264
11007
 
10265
11008
  // src/server.ts
10266
11009
  var import_types3 = require("@modelcontextprotocol/sdk/types.js");
10267
- var import_zod25 = require("zod");
11010
+ var import_zod28 = require("zod");
10268
11011
 
10269
11012
  // src/auth.ts
10270
11013
  var KEY_RE = /^(sk|ssk|st)_(live|test)_/;
@@ -10308,8 +11051,8 @@ function warnOnSuboptimalKey(key, log) {
10308
11051
 
10309
11052
  // src/build-info.ts
10310
11053
  var BUILD_INFO = {
10311
- mcpServer: true ? "0.18.1" : "dev",
10312
- sdk: true ? "0.47.0" : "dev"
11054
+ mcpServer: true ? "0.19.0" : "dev",
11055
+ sdk: true ? "0.49.0" : "dev"
10313
11056
  };
10314
11057
 
10315
11058
  // src/log.ts
@@ -10565,6 +11308,11 @@ ${detail}${trailer}`
10565
11308
  };
10566
11309
  }
10567
11310
 
11311
+ // src/tools/limits.ts
11312
+ var MAX_OWNERSHIP_SCOPES = 2;
11313
+ var MAX_SCOPE_FILTERS = 16;
11314
+ var MAX_CONTENT_TYPES = 2;
11315
+
10568
11316
  // src/tools/hybrid_search.ts
10569
11317
  var MCP_DEFAULT_LIMIT = 3;
10570
11318
  var MCP_MAX_LIMIT = 50;
@@ -10607,11 +11355,11 @@ var inputSchema = {
10607
11355
  folderId: import_zod.z.string().optional().describe("Scope to content in this EXACT folder (Vectros folder id)."),
10608
11356
  rootFolderId: import_zod.z.string().optional().describe("Scope to content under this folder AND all its descendants (subtree-root folder id)."),
10609
11357
  // Content narrowing.
10610
- contentTypes: import_zod.z.array(import_zod.z.enum(["documents", "records"])).optional().describe('Narrow to content types. ["documents"] or ["records"]; omit for unified (both).'),
11358
+ contentTypes: import_zod.z.array(import_zod.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).'),
10611
11359
  typeName: import_zod.z.string().optional().describe(
10612
11360
  '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.'
10613
11361
  ),
10614
- filters: import_zod.z.record(import_zod.z.unknown()).optional().describe(
11362
+ filters: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional().describe(
10615
11363
  '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}}.'
10616
11364
  ),
10617
11365
  // Ownership.
@@ -10619,7 +11367,7 @@ var inputSchema = {
10619
11367
  scope: import_zod.z.string().optional().describe(
10620
11368
  '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.'
10621
11369
  ),
10622
- scopeFilters: import_zod.z.array(import_zod.z.string()).min(1, "scopeFilters must name at least one dimension when supplied").optional().describe(
11370
+ scopeFilters: import_zod.z.array(import_zod.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(
10623
11371
  '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.'
10624
11372
  ),
10625
11373
  // Date window.
@@ -11140,7 +11888,7 @@ var inputSchema5 = {
11140
11888
  status: import_zod5.z.string().optional().describe("Record lifecycle status. Defaults to ACTIVE server-side."),
11141
11889
  folderId: import_zod5.z.string().optional().describe("Group this record into a folder."),
11142
11890
  userId: import_zod5.z.string().optional().describe("Owning user id."),
11143
- scopes: import_zod5.z.array(import_zod5.z.string()).optional().describe(
11891
+ scopes: import_zod5.z.array(import_zod5.z.string()).max(MAX_OWNERSHIP_SCOPES, `scopes accepts at most ${MAX_OWNERSHIP_SCOPES} entries`).optional().describe(
11144
11892
  '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.'
11145
11893
  )
11146
11894
  };
@@ -11198,7 +11946,7 @@ var itemSchema = import_zod6.z.strictObject({
11198
11946
  status: import_zod6.z.string().optional().describe("Record lifecycle status. Defaults to ACTIVE server-side."),
11199
11947
  folderId: import_zod6.z.string().optional().describe("Group this record into a folder."),
11200
11948
  userId: import_zod6.z.string().optional().describe("Owning user id."),
11201
- scopes: import_zod6.z.array(import_zod6.z.string()).optional().describe(
11949
+ scopes: import_zod6.z.array(import_zod6.z.string()).max(MAX_OWNERSHIP_SCOPES, `scopes accepts at most ${MAX_OWNERSHIP_SCOPES} entries`).optional().describe(
11202
11950
  "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."
11203
11951
  )
11204
11952
  });
@@ -11285,7 +12033,7 @@ var inputSchema7 = {
11285
12033
  ),
11286
12034
  status: import_zod7.z.string().optional().describe("Set the record lifecycle status (e.g. ARCHIVED) \u2014 archive/workflow without physical deletion."),
11287
12035
  expectedVersion: import_zod7.z.number().int().optional().describe(
11288
- "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."
12036
+ "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."
11289
12037
  )
11290
12038
  };
11291
12039
  var recordUpdate = ({ client, log }) => ({
@@ -11355,7 +12103,7 @@ var import_zod10 = require("zod");
11355
12103
  // src/tools/provider-alias.ts
11356
12104
  var import_zod9 = require("zod");
11357
12105
  var providerAliasInput = import_zod9.z.string().min(1, "providerAlias must be non-empty when supplied").optional().describe(
11358
- "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."
12106
+ "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."
11359
12107
  );
11360
12108
 
11361
12109
  // src/tools/rag_ask.ts
@@ -11382,14 +12130,14 @@ var inputSchema9 = {
11382
12130
  scope: import_zod10.z.string().optional().describe(
11383
12131
  '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.'
11384
12132
  ),
11385
- scopeFilters: import_zod10.z.array(import_zod10.z.string()).min(1, "scopeFilters must name at least one dimension when supplied").optional().describe(
12133
+ scopeFilters: import_zod10.z.array(import_zod10.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(
11386
12134
  '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`.'
11387
12135
  ),
11388
12136
  folderId: import_zod10.z.string().optional().describe("Restrict retrieval to this exact folder."),
11389
12137
  rootFolderId: import_zod10.z.string().optional().describe("Restrict retrieval to this folder and all its descendants."),
11390
12138
  typeName: import_zod10.z.string().optional().describe("Restrict record retrieval to this schema type."),
11391
- contentTypes: import_zod10.z.array(import_zod10.z.enum(["documents", "records"])).optional().describe('Narrow retrieval to content types. ["documents"] or ["records"]; omit for both.'),
11392
- filters: import_zod10.z.record(import_zod10.z.unknown()).optional().describe(
12139
+ contentTypes: import_zod10.z.array(import_zod10.z.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.'),
12140
+ filters: import_zod10.z.record(import_zod10.z.string(), import_zod10.z.unknown()).optional().describe(
11393
12141
  '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"}.'
11394
12142
  ),
11395
12143
  createdAfter: import_zod10.z.string().optional().describe(
@@ -11664,7 +12412,7 @@ function isNotAvailable(err) {
11664
12412
  var documentGet = ({ client, log }) => ({
11665
12413
  name: "document_get",
11666
12414
  title: "Get document metadata (and optionally text)",
11667
- 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.",
12415
+ 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.",
11668
12416
  inputSchema: inputSchema12,
11669
12417
  // A pure read — never creates, modifies, or deletes anything server-side.
11670
12418
  annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },
@@ -11690,7 +12438,7 @@ var documentGet = ({ client, log }) => ({
11690
12438
  if (isNotAvailable(textErr)) {
11691
12439
  log.debug(
11692
12440
  { tool: "document_get", id },
11693
- "document_get text unavailable (not retained \u2014 storeText:false upload)"
12441
+ "document_get text unavailable (not retained, or no text could be extracted from the file)"
11694
12442
  );
11695
12443
  extra = { ...extra, textAvailable: false };
11696
12444
  } else {
@@ -11743,10 +12491,12 @@ var inputSchema13 = {
11743
12491
  to: import_zod14.z.string().optional().describe("Lookup mode (range): inclusive upper bound; requires `from`."),
11744
12492
  prefix: import_zod14.z.string().optional().describe("Lookup mode (prefix): match values starting with this. Range-enabled string fields only."),
11745
12493
  order: import_zod14.z.enum(["asc", "desc"]).optional().describe(
11746
- "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."
12494
+ "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`."
11747
12495
  ),
11748
- type: import_zod14.z.string().optional().describe("Lookup mode: the document type (the bound schema's type). Required with `field`."),
11749
- // List-mode args:
12496
+ type: import_zod14.z.string().min(1, "type must be non-empty: omit it to list every type").optional().describe(
12497
+ "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."
12498
+ ),
12499
+ // List-mode args (`type` above applies to both modes):
11750
12500
  folderId: import_zod14.z.string().optional().describe("List mode: only documents in this folder (Vectros folder id)."),
11751
12501
  userId: import_zod14.z.string().optional().describe("List mode: scope to documents owned by this user."),
11752
12502
  scope: import_zod14.z.string().optional().describe(
@@ -11760,7 +12510,7 @@ var inputSchema13 = {
11760
12510
  var documentQuery = ({ client, log }) => ({
11761
12511
  name: "document_query",
11762
12512
  title: "Document query (list or lookup)",
11763
- 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.",
12513
+ 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.",
11764
12514
  inputSchema: inputSchema13,
11765
12515
  // A pure read — never creates, modifies, or deletes anything server-side.
11766
12516
  annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },
@@ -11819,7 +12569,19 @@ var documentQuery = ({ client, log }) => ({
11819
12569
  "document_query lookup ok"
11820
12570
  );
11821
12571
  } else {
12572
+ const strayLookupArgs = ["value", "from", "to", "prefix", "order"].filter(
12573
+ (k) => args[k] !== void 0
12574
+ );
12575
+ if (strayLookupArgs.length > 0) {
12576
+ return toolError(
12577
+ "document_query",
12578
+ new Error(
12579
+ `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'.`
12580
+ )
12581
+ );
12582
+ }
11822
12583
  page = await client.documents.listDocuments({
12584
+ type,
11823
12585
  folderId: args.folderId,
11824
12586
  userId: args.userId,
11825
12587
  scope: args.scope,
@@ -11827,7 +12589,7 @@ var documentQuery = ({ client, log }) => ({
11827
12589
  limit
11828
12590
  });
11829
12591
  log.debug(
11830
- { tool: "document_query", mode: "list", limit, returned: pageItems(page).length },
12592
+ { tool: "document_query", mode: "list", type, limit, returned: pageItems(page).length },
11831
12593
  "document_query list ok"
11832
12594
  );
11833
12595
  }
@@ -11862,11 +12624,11 @@ var inputSchema14 = {
11862
12624
  "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."
11863
12625
  ),
11864
12626
  userId: import_zod15.z.string().optional().describe("Reassign the owning user (Vectros UUID)."),
11865
- scopes: import_zod15.z.array(import_zod15.z.string()).optional().describe(
12627
+ scopes: import_zod15.z.array(import_zod15.z.string()).max(MAX_OWNERSHIP_SCOPES, `scopes accepts at most ${MAX_OWNERSHIP_SCOPES} entries`).optional().describe(
11866
12628
  '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).'
11867
12629
  ),
11868
12630
  expectedVersion: import_zod15.z.number().int().optional().describe(
11869
- "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."
12631
+ "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."
11870
12632
  )
11871
12633
  };
11872
12634
  var documentUpdate = ({ client, log }) => ({
@@ -12006,7 +12768,7 @@ var inputSchema17 = {
12006
12768
  "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."
12007
12769
  ),
12008
12770
  userId: import_zod18.z.string().optional().describe("Owning user (Vectros UUID)."),
12009
- scopes: import_zod18.z.array(import_zod18.z.string()).optional().describe(
12771
+ scopes: import_zod18.z.array(import_zod18.z.string()).max(MAX_OWNERSHIP_SCOPES, `scopes accepts at most ${MAX_OWNERSHIP_SCOPES} entries`).optional().describe(
12010
12772
  '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.'
12011
12773
  )
12012
12774
  };
@@ -12020,10 +12782,8 @@ var folderCreate = ({ client, log }) => ({
12020
12782
  // freshly-proved-free value, so the idempotency check running after that derivation can never
12021
12783
  // match on the default path. `slug` is optional, so this is annotated for the less-safe default —
12022
12784
  // the same standard applied to record_create/document_ingest/record_batch_write's identical
12023
- // optional-dedupe-key shape. (A prior version of this annotation claimed unconditional
12024
- // idempotency, reasoning that the derived slug made this tool "genuinely structurally different"
12025
- // from the optional-externalId tools — that reasoning was wrong: the derivation is unconditional,
12026
- // but it is unconditionally NON-colliding by construction, which is the opposite property.)
12785
+ // optional-dedupe-key shape. (The slug derivation being unconditional does not make the tool
12786
+ // idempotent: it is unconditionally NON-colliding by construction, which is the opposite property.)
12027
12787
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },
12028
12788
  handler: async (args) => {
12029
12789
  try {
@@ -12054,11 +12814,11 @@ var inputSchema18 = {
12054
12814
  name: import_zod19.z.string().optional().describe("New folder name. Omit to keep the current name."),
12055
12815
  description: import_zod19.z.string().optional().describe("New description. Omit to leave unchanged."),
12056
12816
  userId: import_zod19.z.string().optional().describe("Reassign the owning user (Vectros UUID)."),
12057
- scopes: import_zod19.z.array(import_zod19.z.string()).optional().describe(
12817
+ scopes: import_zod19.z.array(import_zod19.z.string()).max(MAX_OWNERSHIP_SCOPES, `scopes accepts at most ${MAX_OWNERSHIP_SCOPES} entries`).optional().describe(
12058
12818
  '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).'
12059
12819
  ),
12060
12820
  expectedVersion: import_zod19.z.number().int().optional().describe(
12061
- "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."
12821
+ "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."
12062
12822
  )
12063
12823
  };
12064
12824
  var folderUpdate = ({ client, log }) => ({
@@ -12103,7 +12863,7 @@ var inputSchema19 = {
12103
12863
  var folderDelete = ({ client, log }) => ({
12104
12864
  name: "folder_delete",
12105
12865
  title: "Delete a folder",
12106
- 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.',
12866
+ 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.',
12107
12867
  inputSchema: inputSchema19,
12108
12868
  // Deletes. Idempotent in the standard REST sense: the end state ("this id no longer
12109
12869
  // resolves") is the same whether this is the first delete or a repeat of one.
@@ -12129,7 +12889,7 @@ var inputSchema20 = {
12129
12889
  var currentIdentity = ({ log, apiKey, environment }) => ({
12130
12890
  name: "current_identity",
12131
12891
  title: "Current identity (tenant + principal scope)",
12132
- 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.",
12892
+ 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.",
12133
12893
  inputSchema: inputSchema20,
12134
12894
  // A pure read (/v1/ping) — never creates, modifies, or deletes anything server-side.
12135
12895
  annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },
@@ -12256,14 +13016,14 @@ var inputSchema21 = {
12256
13016
  // Common (both modes):
12257
13017
  folderId: import_zod21.z.string().optional().describe("Optional folder to ingest into. Default: tenant root."),
12258
13018
  userId: import_zod21.z.string().optional().describe("Owning user ID. Optional."),
12259
- scopes: import_zod21.z.array(import_zod21.z.string()).optional().describe(
13019
+ scopes: import_zod21.z.array(import_zod21.z.string()).max(MAX_OWNERSHIP_SCOPES, `scopes accepts at most ${MAX_OWNERSHIP_SCOPES} entries`).optional().describe(
12260
13020
  "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."
12261
13021
  )
12262
13022
  };
12263
13023
  var documentIngest = ({ client, log, transport, ingestRoot }) => ({
12264
13024
  name: "document_ingest",
12265
13025
  title: "Ingest a new document (text body or file upload)",
12266
- 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`.",
13026
+ 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`.",
12267
13027
  inputSchema: inputSchema21,
12268
13028
  // Creates by default, idempotent ONLY when the caller supplies `externalId` (optional,
12269
13029
  // per the doc comment above) — re-ingest then returns the existing document rather than
@@ -12405,7 +13165,7 @@ var documentIngest = ({ client, log, transport, ingestRoot }) => ({
12405
13165
  "document_ingest file ok"
12406
13166
  );
12407
13167
  const uploadCreated = upload?.created;
12408
- 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.";
13168
+ 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.";
12409
13169
  return {
12410
13170
  content: [
12411
13171
  {
@@ -12578,6 +13338,365 @@ var versionHistory = ({ client, log }) => ({
12578
13338
  });
12579
13339
  var version_history_default = versionHistory;
12580
13340
 
13341
+ // src/tools/agent_list.ts
13342
+ var import_zod24 = require("zod");
13343
+ var MCP_DEFAULT_LIMIT6 = 10;
13344
+ var MCP_MAX_LIMIT6 = 100;
13345
+ function toAgentSummary(agent) {
13346
+ return {
13347
+ id: agent.id,
13348
+ name: agent.name,
13349
+ description: agent.description,
13350
+ latestVersion: agent.latestVersion,
13351
+ status: agent.status
13352
+ };
13353
+ }
13354
+ var inputSchema24 = {
13355
+ includeRetired: import_zod24.z.boolean().optional().describe("Also list retired and purged agents (neither can be run). Default false."),
13356
+ startFrom: import_zod24.z.string().optional().describe("Pagination cursor: pass the `nextCursor` from the previous page to fetch the next."),
13357
+ limit: import_zod24.z.number().int().min(1).max(MCP_MAX_LIMIT6).optional().describe(`Max agents per page. Default ${MCP_DEFAULT_LIMIT6}, max ${MCP_MAX_LIMIT6}.`)
13358
+ };
13359
+ var agentList = ({ client, log }) => ({
13360
+ name: "agent_list",
13361
+ title: "List agents",
13362
+ 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.",
13363
+ inputSchema: inputSchema24,
13364
+ // A pure read: it lists definitions and changes nothing.
13365
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },
13366
+ handler: async (args) => {
13367
+ const limit = args.limit ?? MCP_DEFAULT_LIMIT6;
13368
+ try {
13369
+ const page = await client.agents.listAgents({
13370
+ includeRetired: args.includeRetired,
13371
+ startFrom: args.startFrom,
13372
+ limit
13373
+ });
13374
+ const data = (page.data ?? []).map(toAgentSummary);
13375
+ const nextCursor = page.nextCursor ?? null;
13376
+ log.debug({ tool: "agent_list", limit, returned: data.length }, "agent_list ok");
13377
+ return { content: [{ type: "text", text: JSON.stringify({ data, nextCursor }, null, 2) }] };
13378
+ } catch (err) {
13379
+ log.warn({ tool: "agent_list", err: String(err) }, "agent_list failed");
13380
+ return toolError("agent_list", err);
13381
+ }
13382
+ }
13383
+ });
13384
+ var agent_list_default = agentList;
13385
+
13386
+ // src/tools/agent_run.ts
13387
+ var import_node_crypto = require("crypto");
13388
+ var import_zod25 = require("zod");
13389
+
13390
+ // src/run-stream.ts
13391
+ var TEXT_PROGRESS_CHARS = 256;
13392
+ var HEARTBEAT_MS = 15e3;
13393
+ var TERMINAL_STATUS = {
13394
+ "run.completed": "COMPLETED",
13395
+ "run.failed": "FAILED",
13396
+ "run.cancelled": "CANCELLED"
13397
+ };
13398
+ function str(v) {
13399
+ return typeof v === "string" && v.length > 0 ? v : void 0;
13400
+ }
13401
+ function num(v) {
13402
+ return typeof v === "number" && Number.isFinite(v) ? v : void 0;
13403
+ }
13404
+ async function consumeRunStream(stream, initialRunId, onProgress, heartbeatMs = HEARTBEAT_MS) {
13405
+ const result = {
13406
+ runId: initialRunId,
13407
+ terminal: false,
13408
+ status: "UNKNOWN",
13409
+ text: "",
13410
+ toolCalls: []
13411
+ };
13412
+ const blocks = [];
13413
+ let pending = "";
13414
+ let unsentChars = 0;
13415
+ const emit = async (message) => {
13416
+ if (!onProgress) return;
13417
+ try {
13418
+ await onProgress(message);
13419
+ } catch {
13420
+ }
13421
+ };
13422
+ let heartbeat;
13423
+ let lastEventAt = Date.now();
13424
+ if (onProgress) {
13425
+ heartbeat = setInterval(() => {
13426
+ if (Date.now() - lastEventAt >= heartbeatMs) {
13427
+ lastEventAt = Date.now();
13428
+ void emit("run still working");
13429
+ }
13430
+ }, Math.max(1, Math.floor(heartbeatMs / 3)));
13431
+ heartbeat.unref?.();
13432
+ }
13433
+ try {
13434
+ for await (const raw of stream) {
13435
+ lastEventAt = Date.now();
13436
+ if (!raw || typeof raw !== "object") continue;
13437
+ const ev = raw;
13438
+ result.runId ??= str(ev.runId);
13439
+ const type = typeof ev.type === "string" ? ev.type : "";
13440
+ switch (type) {
13441
+ case "run.started":
13442
+ result.agentId = str(ev.agentId) ?? result.agentId;
13443
+ result.agentVersion = num(ev.agentVersion) ?? result.agentVersion;
13444
+ await emit("run started");
13445
+ break;
13446
+ case "message.delta": {
13447
+ const piece = typeof ev.text === "string" ? ev.text : "";
13448
+ pending += piece;
13449
+ unsentChars += piece.length;
13450
+ if (unsentChars >= TEXT_PROGRESS_CHARS) {
13451
+ unsentChars = 0;
13452
+ await emit(`answer: ${blocks.join("\n\n").length + pending.length} characters so far`);
13453
+ }
13454
+ break;
13455
+ }
13456
+ case "message.completed": {
13457
+ const full = str(ev.text) ?? pending;
13458
+ if (full.length > 0) blocks.push(full);
13459
+ pending = "";
13460
+ unsentChars = 0;
13461
+ await emit("model call completed");
13462
+ break;
13463
+ }
13464
+ case "tool.completed": {
13465
+ const call = {
13466
+ tool: str(ev.tool),
13467
+ outcome: str(ev.outcome),
13468
+ code: str(ev.code)
13469
+ };
13470
+ result.toolCalls.push(call);
13471
+ await emit(`tool ${call.tool ?? "call"}: ${call.outcome ?? "ended"}`);
13472
+ break;
13473
+ }
13474
+ default:
13475
+ break;
13476
+ }
13477
+ if (ev.terminal === true || Object.hasOwn(TERMINAL_STATUS, type)) {
13478
+ result.terminal = true;
13479
+ result.status = str(ev.status) ?? TERMINAL_STATUS[type] ?? "ENDED";
13480
+ result.reason = str(ev.reason);
13481
+ result.errorCode = str(ev.errorCode);
13482
+ if (typeof ev.settled === "boolean" || ev.inferenceBalanceCentsChargedMilli !== void 0 || ev.inferenceBalanceCentsRefundedMilli !== void 0) {
13483
+ result.charged = {
13484
+ settled: typeof ev.settled === "boolean" ? ev.settled : void 0,
13485
+ inferenceBalanceCentsChargedMilli: num(ev.inferenceBalanceCentsChargedMilli),
13486
+ inferenceBalanceCentsRefundedMilli: num(ev.inferenceBalanceCentsRefundedMilli)
13487
+ };
13488
+ }
13489
+ break;
13490
+ }
13491
+ }
13492
+ } catch (err) {
13493
+ result.streamError = err instanceof Error ? err.message : String(err);
13494
+ } finally {
13495
+ if (heartbeat) clearInterval(heartbeat);
13496
+ }
13497
+ if (pending.length > 0) blocks.push(pending);
13498
+ result.text = blocks.join("\n\n");
13499
+ return result;
13500
+ }
13501
+
13502
+ // src/tools/agent_run.ts
13503
+ var RUN_ID_HEADER = "x-vectros-run-id";
13504
+ var MAX_INPUT_CHARS = 1e5;
13505
+ var MAX_INPUT_BYTES = 24e4;
13506
+ function encodedInputBytes(v) {
13507
+ return Buffer.byteLength(JSON.stringify(v), "utf8");
13508
+ }
13509
+ var TERMINAL_EVENT_TYPES = /* @__PURE__ */ new Set(["run.completed", "run.failed", "run.cancelled"]);
13510
+ var ENDED_STATUSES = /* @__PURE__ */ new Set(["COMPLETED", "FAILED", "CANCELLED", "EXPIRED"]);
13511
+ var inputSchema25 = {
13512
+ agentId: import_zod25.z.string().min(1, "agentId must be non-empty").describe("The agent to run: an `id` from agent_list."),
13513
+ input: import_zod25.z.string().min(1, "input must be non-empty").max(MAX_INPUT_CHARS, `input accepts at most ${MAX_INPUT_CHARS} characters`).refine(
13514
+ (v) => encodedInputBytes(v) <= MAX_INPUT_BYTES,
13515
+ `input accepts at most ${MAX_INPUT_BYTES} bytes as sent (a JSON string in UTF-8)`
13516
+ ).describe(
13517
+ `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).`
13518
+ ),
13519
+ agentVersion: import_zod25.z.number().int().min(1).optional().describe("The agent version to run. Default: its latest version."),
13520
+ maxInferenceCents: import_zod25.z.number().int().min(1).optional().describe(
13521
+ "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`."
13522
+ ),
13523
+ readOnly: import_zod25.z.boolean().optional().describe("When true, every tool call that would change data is refused in this run. Default false."),
13524
+ idempotencyKey: import_zod25.z.string().regex(/^[A-Za-z0-9._:-]{1,128}$/, "idempotencyKey is 1 to 128 letters, digits, `.`, `_`, `:` or `-`").optional().describe(
13525
+ "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."
13526
+ )
13527
+ };
13528
+ var agentRun = ({ client, log }) => ({
13529
+ name: "agent_run",
13530
+ title: "Run an agent",
13531
+ 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.",
13532
+ inputSchema: inputSchema25,
13533
+ // Not a read: a run is billed, and its tool calls may create, change or delete data with the
13534
+ // caller's permissions, so a host should confirm it. Not idempotent: each call is a new paid run
13535
+ // unless the same idempotencyKey is passed again.
13536
+ annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
13537
+ handler: async (args, extra) => {
13538
+ const agentId = args.agentId;
13539
+ const maxInferenceCents = args.maxInferenceCents;
13540
+ const idempotencyKey = args.idempotencyKey ?? (0, import_node_crypto.randomUUID)();
13541
+ const request = {
13542
+ "Idempotency-Key": idempotencyKey,
13543
+ agentId,
13544
+ agentVersion: args.agentVersion,
13545
+ input: { text: args.input },
13546
+ budget: maxInferenceCents !== void 0 ? { maxInferenceCents } : void 0,
13547
+ readOnly: args.readOnly
13548
+ };
13549
+ const progressToken = extra._meta?.progressToken;
13550
+ let progressCount = 0;
13551
+ const onProgress = progressToken !== void 0 && extra.sendNotification ? async (message) => {
13552
+ progressCount += 1;
13553
+ await extra.sendNotification({
13554
+ method: "notifications/progress",
13555
+ params: { progressToken, progress: progressCount, message }
13556
+ });
13557
+ } : void 0;
13558
+ const streamAbort = new AbortController();
13559
+ const callSignal = extra.signal;
13560
+ let knownRunId;
13561
+ let headersReceived = false;
13562
+ let cancelRequested = false;
13563
+ let cancelSent = false;
13564
+ let runEnded = false;
13565
+ const sendCancel = () => {
13566
+ if (!cancelRequested || cancelSent || !knownRunId || runEnded) return;
13567
+ cancelSent = true;
13568
+ const id = knownRunId;
13569
+ client.agents.cancelRun({ id }).then(
13570
+ () => log.info({ tool: "agent_run", runId: id }, "agent_run cancelled by the client"),
13571
+ (err) => log.warn({ tool: "agent_run", runId: id, err: String(err) }, "agent_run cancel failed")
13572
+ );
13573
+ };
13574
+ const cancelIfNamed = () => {
13575
+ if (!cancelRequested || !headersReceived || !knownRunId) return;
13576
+ sendCancel();
13577
+ streamAbort.abort();
13578
+ };
13579
+ const onCancel = () => {
13580
+ cancelRequested = true;
13581
+ cancelIfNamed();
13582
+ };
13583
+ if (callSignal?.aborted) {
13584
+ return toolError("agent_run", new Error("The call was cancelled before the run started."));
13585
+ }
13586
+ callSignal?.addEventListener("abort", onCancel, { once: true });
13587
+ try {
13588
+ const { data: stream, rawResponse } = await client.agents.createRun(request, { abortSignal: streamAbort.signal }).withRawResponse();
13589
+ headersReceived = true;
13590
+ knownRunId = rawResponse.headers.get(RUN_ID_HEADER) ?? void 0;
13591
+ cancelIfNamed();
13592
+ const naming = async function* () {
13593
+ for await (const ev of stream) {
13594
+ if (!knownRunId && ev && typeof ev === "object") {
13595
+ const id = ev.runId;
13596
+ if (typeof id === "string" && id.length > 0) {
13597
+ knownRunId = id;
13598
+ cancelIfNamed();
13599
+ }
13600
+ }
13601
+ if (ev && typeof ev === "object") {
13602
+ const e = ev;
13603
+ if (e.terminal === true || typeof e.type === "string" && TERMINAL_EVENT_TYPES.has(e.type)) runEnded = true;
13604
+ }
13605
+ yield ev;
13606
+ }
13607
+ };
13608
+ const run = await consumeRunStream(naming(), knownRunId, onProgress);
13609
+ knownRunId ??= run.runId;
13610
+ if (run.terminal) runEnded = true;
13611
+ sendCancel();
13612
+ log.debug(
13613
+ {
13614
+ tool: "agent_run",
13615
+ runId: run.runId,
13616
+ status: run.status,
13617
+ terminal: run.terminal,
13618
+ toolCalls: run.toolCalls.length,
13619
+ textLength: run.text.length
13620
+ },
13621
+ "agent_run ok"
13622
+ );
13623
+ const body = {
13624
+ runId: run.runId,
13625
+ agentId: run.agentId ?? agentId,
13626
+ agentVersion: run.agentVersion,
13627
+ status: run.status,
13628
+ terminal: run.terminal,
13629
+ reason: run.reason,
13630
+ errorCode: run.errorCode,
13631
+ text: run.text,
13632
+ toolCalls: run.toolCalls,
13633
+ charged: run.charged
13634
+ };
13635
+ if (!run.terminal) {
13636
+ 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).";
13637
+ }
13638
+ return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
13639
+ } catch (err) {
13640
+ const e = err;
13641
+ if (e?.body?.errorCode === "IDEMPOTENCY_IN_PROGRESS") {
13642
+ const runId = (typeof e.body.runId === "string" ? e.body.runId : void 0) ?? e.rawResponse?.headers?.get?.(RUN_ID_HEADER) ?? void 0;
13643
+ if (runId) {
13644
+ const status = typeof e.body.status === "string" ? e.body.status : void 0;
13645
+ log.info({ tool: "agent_run", runId }, "agent_run: the idempotency key already started a run");
13646
+ const body = {
13647
+ runId,
13648
+ agentId,
13649
+ status,
13650
+ // The 409 names the run's status at the time; an ended status is final.
13651
+ terminal: status !== void 0 && ENDED_STATUSES.has(status),
13652
+ alreadyStarted: true,
13653
+ 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."
13654
+ };
13655
+ return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
13656
+ }
13657
+ }
13658
+ log.warn({ tool: "agent_run", agentId, err: String(err) }, "agent_run failed");
13659
+ const result = toolError("agent_run", err);
13660
+ const statusCode = err?.statusCode;
13661
+ if (typeof statusCode !== "number" || statusCode === 408 || statusCode >= 500) {
13662
+ result.content[0].text += `
13663
+ idempotencyKey: ${idempotencyKey}
13664
+ 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.)" : "");
13665
+ }
13666
+ return result;
13667
+ } finally {
13668
+ callSignal?.removeEventListener("abort", onCancel);
13669
+ }
13670
+ }
13671
+ });
13672
+ var agent_run_default = agentRun;
13673
+
13674
+ // src/tools/run_get.ts
13675
+ var import_zod26 = require("zod");
13676
+ var inputSchema26 = {
13677
+ runId: import_zod26.z.string().min(1, "runId must be non-empty").describe("The run id agent_run returned (`runId`).")
13678
+ };
13679
+ var runGet = ({ client, log }) => ({
13680
+ name: "run_get",
13681
+ title: "Get an agent run",
13682
+ 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.",
13683
+ inputSchema: inputSchema26,
13684
+ // A pure read: polling a run does not change it.
13685
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true },
13686
+ handler: async (args) => {
13687
+ const runId = args.runId;
13688
+ try {
13689
+ const run = await client.agents.getRun({ id: runId });
13690
+ log.debug({ tool: "run_get", runId, status: run.status, terminal: run.terminal }, "run_get ok");
13691
+ return { content: [{ type: "text", text: JSON.stringify(run, null, 2) }] };
13692
+ } catch (err) {
13693
+ log.warn({ tool: "run_get", runId, err: String(err) }, "run_get failed");
13694
+ return toolError("run_get", err);
13695
+ }
13696
+ }
13697
+ });
13698
+ var run_get_default = runGet;
13699
+
12581
13700
  // src/tools/types.ts
12582
13701
  var TOOL_NAMES = [
12583
13702
  "hybrid_search",
@@ -12602,7 +13721,10 @@ var TOOL_NAMES = [
12602
13721
  "current_identity",
12603
13722
  "document_ingest",
12604
13723
  "lookup_principal",
12605
- "version_history"
13724
+ "version_history",
13725
+ "agent_list",
13726
+ "agent_run",
13727
+ "run_get"
12606
13728
  ];
12607
13729
 
12608
13730
  // src/tools/index.ts
@@ -12629,7 +13751,10 @@ var ALL_TOOL_FACTORIES = {
12629
13751
  current_identity: current_identity_default,
12630
13752
  document_ingest: document_ingest_default,
12631
13753
  lookup_principal: lookup_principal_default,
12632
- version_history: version_history_default
13754
+ version_history: version_history_default,
13755
+ agent_list: agent_list_default,
13756
+ agent_run: agent_run_default,
13757
+ run_get: run_get_default
12633
13758
  };
12634
13759
 
12635
13760
  // src/resources/schemas.ts
@@ -12653,7 +13778,7 @@ var identityResource = ({ log, apiKey, environment }) => ({
12653
13778
  name: "identity",
12654
13779
  uri: "vectros://identity",
12655
13780
  title: "Current identity (tenant + principal scope)",
12656
- 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.",
13781
+ 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.",
12657
13782
  mimeType: "application/json",
12658
13783
  read: async () => {
12659
13784
  const identity = await resolveIdentity({ log, apiKey, environment });
@@ -12672,11 +13797,12 @@ var ALL_RESOURCE_FACTORIES = {
12672
13797
  };
12673
13798
 
12674
13799
  // src/zod-to-json-schema.ts
12675
- var import_zod24 = require("zod");
13800
+ var import_zod27 = require("zod");
12676
13801
  function zodShapeToJsonSchema(shape) {
12677
13802
  const properties = {};
12678
13803
  const required = [];
12679
- for (const [name, schema] of Object.entries(shape)) {
13804
+ for (const [name, entry] of Object.entries(shape)) {
13805
+ const schema = entry;
12680
13806
  properties[name] = zodTypeToJsonSchema(schema);
12681
13807
  if (!schema.isOptional()) required.push(name);
12682
13808
  }
@@ -12685,43 +13811,45 @@ function zodShapeToJsonSchema(shape) {
12685
13811
  return out;
12686
13812
  }
12687
13813
  function zodTypeToJsonSchema(schema) {
12688
- const description = schema.description;
13814
+ const descriptionOf = (s) => s.description;
13815
+ let description = descriptionOf(schema);
12689
13816
  let current = schema;
12690
- while (current instanceof import_zod24.z.ZodOptional || current instanceof import_zod24.z.ZodDefault || current instanceof import_zod24.z.ZodNullable) {
13817
+ while (current instanceof import_zod27.z.ZodOptional || current instanceof import_zod27.z.ZodDefault || current instanceof import_zod27.z.ZodNullable) {
12691
13818
  current = current._def.innerType;
13819
+ description ??= descriptionOf(current);
12692
13820
  }
12693
13821
  const base = description ? { description } : {};
12694
- if (current instanceof import_zod24.z.ZodString) {
13822
+ if (current instanceof import_zod27.z.ZodString) {
12695
13823
  return { ...base, type: "string" };
12696
13824
  }
12697
- if (current instanceof import_zod24.z.ZodNumber) {
13825
+ if (current instanceof import_zod27.z.ZodNumber) {
12698
13826
  return { ...base, type: "number" };
12699
13827
  }
12700
- if (current instanceof import_zod24.z.ZodBoolean) {
13828
+ if (current instanceof import_zod27.z.ZodBoolean) {
12701
13829
  return { ...base, type: "boolean" };
12702
13830
  }
12703
- if (current instanceof import_zod24.z.ZodEnum) {
13831
+ if (current instanceof import_zod27.z.ZodEnum) {
12704
13832
  return {
12705
13833
  ...base,
12706
13834
  type: "string",
12707
13835
  enum: current.options
12708
13836
  };
12709
13837
  }
12710
- if (current instanceof import_zod24.z.ZodArray) {
13838
+ if (current instanceof import_zod27.z.ZodArray) {
12711
13839
  return {
12712
13840
  ...base,
12713
13841
  type: "array",
12714
13842
  items: zodTypeToJsonSchema(current.element)
12715
13843
  };
12716
13844
  }
12717
- if (current instanceof import_zod24.z.ZodObject) {
13845
+ if (current instanceof import_zod27.z.ZodObject) {
12718
13846
  return {
12719
13847
  ...base,
12720
13848
  ...zodShapeToJsonSchema(current.shape)
12721
13849
  };
12722
13850
  }
12723
- if (current instanceof import_zod24.z.ZodRecord) {
12724
- const valueType = current._def.valueType;
13851
+ if (current instanceof import_zod27.z.ZodRecord) {
13852
+ const valueType = current.valueType;
12725
13853
  return {
12726
13854
  ...base,
12727
13855
  type: "object",
@@ -12849,7 +13977,7 @@ var VectrosMCPServer = class {
12849
13977
  if (!tool) {
12850
13978
  result = toolError(req.params.name ?? "unknown", new Error("No such tool."));
12851
13979
  } else {
12852
- const parsed = import_zod25.z.object(tool.inputSchema).strict().safeParse(req.params.arguments ?? {});
13980
+ const parsed = import_zod28.z.object(tool.inputSchema).strict().safeParse(req.params.arguments ?? {});
12853
13981
  if (!parsed.success) {
12854
13982
  result = toolError(tool.name, new Error(formatArgError(tool, parsed.error)));
12855
13983
  } else {
@@ -12912,7 +14040,7 @@ var VectrosMCPServer = class {
12912
14040
  *
12913
14041
  * If `validateOnStart` (default true) is enabled, performs a
12914
14042
  * GET /v1/ping check BEFORE wiring the transport. On failure,
12915
- * throws — the partner's MCP client sees a startup error instead
14043
+ * throws — your MCP client sees a startup error instead
12916
14044
  * of a confusing "tools work but the first call 401s" experience.
12917
14045
  */
12918
14046
  async connect(transport) {