@rulvar/anthropic 1.231.0 → 1.233.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.d.ts CHANGED
@@ -87,6 +87,19 @@ interface AnthropicAdapterOptions {
87
87
  * structural `AnthropicClientLike` mock (tests).
88
88
  */
89
89
  client?: Anthropic | AnthropicClientLike;
90
+ /**
91
+ * The `refreshCaps()` pagination bound (RV2904), the MCP `maxPages`
92
+ * doctrine applied to the provider's own metadata surface: past this
93
+ * many pages with more still reported, the refresh fails typed
94
+ * instead of truncating, because a silently partial caps table would
95
+ * clamp output bounds against limits that are not the model's.
96
+ * Cursor cycles (a page answering the cursor it was queried with, or
97
+ * one this sweep already used) are refused UNCONDITIONALLY, bound or
98
+ * none: a cycle is never a legitimate pagination step. Unset keeps
99
+ * pagination unbounded exactly like MCP without a declared cap, with
100
+ * only the cycle guards armed.
101
+ */
102
+ capsMaxPages?: number;
90
103
  }
91
104
  /**
92
105
  * Creates the first-class Anthropic adapter (id 'anthropic'). SDK
package/dist/index.js CHANGED
@@ -807,6 +807,8 @@ function resolveAnthropicClient(options) {
807
807
  */
808
808
  function anthropic(options = {}) {
809
809
  const client = resolveAnthropicClient(options);
810
+ const capsMaxPages = options.capsMaxPages;
811
+ if (capsMaxPages !== void 0 && (!Number.isInteger(capsMaxPages) || capsMaxPages < 1)) throw new ConfigError(`anthropic(): capsMaxPages must be a positive integer; got ${JSON.stringify(capsMaxPages)}`);
810
812
  const ids = new IdMap(createCanonicalIdMinter());
811
813
  const refreshed = /* @__PURE__ */ new Map();
812
814
  function infoFor(model) {
@@ -830,8 +832,11 @@ function anthropic(options = {}) {
830
832
  },
831
833
  async refreshCaps() {
832
834
  let afterId;
835
+ const visited = /* @__PURE__ */ new Set();
836
+ let pages = 0;
833
837
  do {
834
838
  const page = await client.models.list(afterId === void 0 ? {} : { after_id: afterId });
839
+ pages += 1;
835
840
  for (const model of page.data) {
836
841
  const id = model.id;
837
842
  if (typeof id !== "string") continue;
@@ -840,7 +845,12 @@ function anthropic(options = {}) {
840
845
  if (typeof model.max_tokens === "number") patch.maxOutputTokens = model.max_tokens;
841
846
  if (Object.keys(patch).length > 0) refreshed.set(id, patch);
842
847
  }
843
- afterId = page.has_more === true && typeof page.last_id === "string" ? page.last_id : void 0;
848
+ if (afterId !== void 0) visited.add(afterId);
849
+ const next = page.has_more === true && typeof page.last_id === "string" ? page.last_id : void 0;
850
+ if (next !== void 0 && next === afterId) throw new ConfigError(`anthropic: models.list returned the cursor it was queried with ('${next}') on page ${String(pages)}: the pagination makes no progress`);
851
+ if (next !== void 0 && visited.has(next)) throw new ConfigError(`anthropic: models.list returned a cursor this sweep already visited ('${next}') on page ${String(pages)}: the pagination cycles`);
852
+ if (capsMaxPages !== void 0 && pages >= capsMaxPages && next !== void 0) throw new ConfigError(`anthropic: models.list still reports another page after ${String(pages)} page(s), over the declared capsMaxPages ${String(capsMaxPages)}; raise the cap or trim the account`);
853
+ afterId = next;
844
854
  } while (afterId !== void 0);
845
855
  },
846
856
  async *stream(req, signal, hooks) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulvar/anthropic",
3
- "version": "1.231.0",
3
+ "version": "1.233.0",
4
4
  "description": "Rulvar first-class provider adapter over @anthropic-ai/sdk.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -23,13 +23,13 @@
23
23
  },
24
24
  "dependencies": {
25
25
  "@anthropic-ai/sdk": "^0.115.0",
26
- "@rulvar/core": "1.231.0"
26
+ "@rulvar/core": "1.233.0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/node": "^22.20.1",
30
30
  "tsdown": "^0.22.14",
31
31
  "typescript": "~6.0.3",
32
- "@rulvar/testing": "1.231.0"
32
+ "@rulvar/testing": "1.233.0"
33
33
  },
34
34
  "repository": {
35
35
  "type": "git",