@rulvar/anthropic 1.0.0 → 1.1.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
@@ -67,6 +67,12 @@ declare class IdMap {
67
67
  }
68
68
  type Block = Record<string, unknown>;
69
69
  /**
70
+ * Returns a deep copy of the schema with the unsupported keywords
71
+ * removed at SCHEMA positions only: a property literally named
72
+ * "minimum" (a key inside `properties`) survives. The input is never
73
+ * mutated; unrecognized keywords are copied through untouched.
74
+ */
75
+ /**
70
76
  * Builds Messages API params from a ChatRequest. cacheHint compiles into
71
77
  * cache_control breakpoints; beyond the provider cap of 4 the DEEPEST
72
78
  * breakpoints are kept and the shallowest dropped, deterministically
package/dist/index.js CHANGED
@@ -54,6 +54,22 @@ const ANTHROPIC_MODELS = {
54
54
  cacheRead: .3,
55
55
  cacheWrite: 3.75
56
56
  }, 2048),
57
+ "claude-haiku-4-5": (() => {
58
+ const base = current(2e5, 64e3, {
59
+ in: 1,
60
+ out: 5,
61
+ cacheRead: .1,
62
+ cacheWrite: 1.25
63
+ }, 2048);
64
+ return {
65
+ ...base,
66
+ caps: {
67
+ ...base.caps,
68
+ reasoningEfforts: []
69
+ },
70
+ thinkingForm: "enabled-budget"
71
+ };
72
+ })(),
57
73
  "claude-opus-4-6": {
58
74
  ...current(2e5, 32e3, {
59
75
  in: 15,
@@ -126,6 +142,75 @@ var IdMap = class {
126
142
  return wireId;
127
143
  }
128
144
  };
145
+ /**
146
+ * Keywords the constrained-decoding schema validator rejects with a
147
+ * live 400 ("For 'integer' type, property 'minimum' is not
148
+ * supported"): every numeric bound plus, asymmetrically, maxItems
149
+ * (minItems, the string bounds, pattern, format, enum and const all
150
+ * pass). The validator guards exactly two wire positions: tools sent
151
+ * with strict: true and output_config.format json_schema; plain tools
152
+ * accept full JSON Schema. Probed live on claude-sonnet-5, 2026-07-11
153
+ * (docs/04, section 4.3). The engine still validates tool args and
154
+ * structured output against the UNSCRUBBED schema, so the dropped
155
+ * keywords stay enforced; only the model-side hint is lost.
156
+ */
157
+ const CONSTRAINED_DECODING_UNSUPPORTED = /* @__PURE__ */ new Set([
158
+ "minimum",
159
+ "maximum",
160
+ "exclusiveMinimum",
161
+ "exclusiveMaximum",
162
+ "multipleOf",
163
+ "maxItems"
164
+ ]);
165
+ /** Keywords whose value is a map of property NAMES to schemas. */
166
+ const SCHEMA_MAP_KEYWORDS = /* @__PURE__ */ new Set([
167
+ "properties",
168
+ "patternProperties",
169
+ "$defs",
170
+ "definitions"
171
+ ]);
172
+ /** Keywords whose value is a schema or an array of schemas. */
173
+ const SCHEMA_VALUE_KEYWORDS = /* @__PURE__ */ new Set([
174
+ "items",
175
+ "prefixItems",
176
+ "additionalProperties",
177
+ "additionalItems",
178
+ "propertyNames",
179
+ "contains",
180
+ "anyOf",
181
+ "oneOf",
182
+ "allOf",
183
+ "not",
184
+ "if",
185
+ "then",
186
+ "else"
187
+ ]);
188
+ /**
189
+ * Returns a deep copy of the schema with the unsupported keywords
190
+ * removed at SCHEMA positions only: a property literally named
191
+ * "minimum" (a key inside `properties`) survives. The input is never
192
+ * mutated; unrecognized keywords are copied through untouched.
193
+ */
194
+ function scrubForConstrainedDecoding(schema) {
195
+ if (Array.isArray(schema)) return schema.map((entry) => scrubForConstrainedDecoding(entry));
196
+ if (schema === null || typeof schema !== "object") return schema;
197
+ const out = {};
198
+ for (const [key, value] of Object.entries(schema)) {
199
+ if (CONSTRAINED_DECODING_UNSUPPORTED.has(key)) continue;
200
+ if (SCHEMA_MAP_KEYWORDS.has(key) && value !== null && typeof value === "object") {
201
+ const map = {};
202
+ for (const [name, sub] of Object.entries(value)) map[name] = scrubForConstrainedDecoding(sub);
203
+ out[key] = map;
204
+ continue;
205
+ }
206
+ if (SCHEMA_VALUE_KEYWORDS.has(key)) {
207
+ out[key] = scrubForConstrainedDecoding(value);
208
+ continue;
209
+ }
210
+ out[key] = value;
211
+ }
212
+ return out;
213
+ }
129
214
  function cacheControl(ttl) {
130
215
  return ttl === "1h" ? {
131
216
  type: "ephemeral",
@@ -203,12 +288,15 @@ function buildAnthropicParams(req, options) {
203
288
  if (systemBlocks.length > 0) params.system = systemBlocks;
204
289
  if (req.stopSequences !== void 0) params.stop_sequences = req.stopSequences;
205
290
  if (req.tools !== void 0) {
206
- params.tools = req.tools.map((tool) => ({
207
- name: tool.name,
208
- description: tool.description,
209
- input_schema: tool.parameters,
210
- ...isStrictCompatibleSchema(tool.parameters) ? { strict: true } : {}
211
- }));
291
+ params.tools = req.tools.map((tool) => {
292
+ const strict = isStrictCompatibleSchema(tool.parameters);
293
+ return {
294
+ name: tool.name,
295
+ description: tool.description,
296
+ input_schema: strict ? scrubForConstrainedDecoding(tool.parameters) : tool.parameters,
297
+ ...strict ? { strict: true } : {}
298
+ };
299
+ });
212
300
  if (req.toolChoice === "required") params.tool_choice = { type: "any" };
213
301
  else if (typeof req.toolChoice === "object") params.tool_choice = {
214
302
  type: "tool",
@@ -222,7 +310,7 @@ function buildAnthropicParams(req, options) {
222
310
  if (req.effort !== void 0) outputConfig.effort = req.effort;
223
311
  if (req.schema !== void 0) outputConfig.format = {
224
312
  type: "json_schema",
225
- schema: req.schema
313
+ schema: scrubForConstrainedDecoding(req.schema)
226
314
  };
227
315
  if (anthropicOptions.task_budget !== void 0) outputConfig.task_budget = anthropicOptions.task_budget;
228
316
  if (Object.keys(outputConfig).length > 0) params.output_config = outputConfig;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulvar/anthropic",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "rulvar first-class provider adapter over @anthropic-ai/sdk.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -23,7 +23,7 @@
23
23
  },
24
24
  "dependencies": {
25
25
  "@anthropic-ai/sdk": "^0.110.0",
26
- "@rulvar/core": "1.0.0"
26
+ "@rulvar/core": "1.1.0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/node": "^22.20.0",