@mochabug/adapt-sdk 0.4.0 → 0.4.2

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.
@@ -1,5 +1,13 @@
1
1
  import type { JTDSchemaJson, SignalDescriptorJson } from '../api';
2
- /** JSON Schema subset supported by Anthropic structured output. */
2
+ /**
3
+ * JSON Schema subset accepted by the Anthropic structured-output API.
4
+ *
5
+ * This is the provider-specific representation produced by
6
+ * {@link AnthropicConversion}. It covers the keywords that Anthropic
7
+ * inspects when constraining model output: `type`, `properties`, `required`,
8
+ * `additionalProperties`, `enum`, `const`, `format`, `items`, `anyOf`,
9
+ * `$defs`, `$ref`, and `description`.
10
+ */
3
11
  export interface AnthropicSchema {
4
12
  type?: string | string[];
5
13
  description?: string;
@@ -14,40 +22,235 @@ export interface AnthropicSchema {
14
22
  $defs?: Record<string, AnthropicSchema>;
15
23
  $ref?: string;
16
24
  }
17
- export interface ConvertSuccess {
25
+ /**
26
+ * Successful conversion result for a JTD format.
27
+ *
28
+ * Returned when the raw LLM output has been coerced to match the JTD schema
29
+ * and passes JTD validation. `data` contains the deserialized, coerced, and
30
+ * JTD-validated JSON value.
31
+ */
32
+ export interface ConvertSuccessJson {
18
33
  success: true;
34
+ kind: 'json';
35
+ /** The deserialized, coerced, and JTD-validated JSON value. */
19
36
  data: unknown;
20
37
  }
38
+ /**
39
+ * Successful conversion result for a MIME (binary) format.
40
+ *
41
+ * Returned when the raw LLM output matches a MIME format. The base64 string
42
+ * produced by the model is decoded into raw binary bytes.
43
+ */
44
+ export interface ConvertSuccessBinary {
45
+ success: true;
46
+ kind: 'binary';
47
+ /** The concrete MIME type of the binary content (e.g. `"image/png"`). */
48
+ mimeType: string;
49
+ /** The raw binary data decoded from the base64 string returned by the LLM. */
50
+ data: Uint8Array;
51
+ /** Optional filename, provided by the caller if available. */
52
+ filename?: string;
53
+ }
54
+ /**
55
+ * Failed conversion result.
56
+ *
57
+ * `errors` contains one or more human-readable strings describing validation
58
+ * or coercion failures. Each entry uses a JSON Pointer path prefix
59
+ * (e.g. `"/foo/bar: ..."`) to locate the problem within the data.
60
+ */
21
61
  export interface ConvertFailure {
22
62
  success: false;
63
+ /** Array of human-readable error messages with JSON Pointer path prefixes. */
23
64
  errors: string[];
24
65
  }
25
- export type ConvertResult = ConvertSuccess | ConvertFailure;
26
- export interface AnthropicConversionResult {
27
- /** Anthropic structured output compatible JSON Schema. */
28
- schema: AnthropicSchema;
29
- /** Whether the schema supports strict mode. False for unstructured (empty) schemas. */
30
- strict: boolean;
31
- /** Convert Anthropic JSON output back to JTD-conforming JSON. */
32
- convert: (anthropicJson: unknown) => ConvertResult;
33
- }
34
66
  /**
35
- * Convert a JTD schema to an Anthropic structured output compatible JSON Schema,
36
- * with a converter function that transforms and validates Anthropic output against
37
- * the original JTD schema.
67
+ * Discriminated union of conversion outcomes.
38
68
  *
39
- * @throws {Error} if the JTD schema contains recursive definitions (not supported by Anthropic).
40
- * @throws {Error} if the JTD schema contains unresolved refs.
69
+ * Check `success` first, then narrow on `kind` (`'json'` or `'binary'`)
70
+ * for successful results.
41
71
  */
42
- export declare function convertToAnthropicSchema(jtdSchema: JTDSchemaJson): AnthropicConversionResult;
72
+ export type ConvertResult = ConvertSuccessJson | ConvertSuccessBinary | ConvertFailure;
43
73
  /**
44
- * Convert a SignalDescriptorJson to an Anthropic structured output compatible JSON Schema.
74
+ * Converts JTD schemas or Adapt signal descriptors into Anthropic-compatible
75
+ * JSON Schema, and converts raw LLM output back into validated data.
76
+ *
77
+ * ### JTD form mapping
78
+ * - **type** -- mapped to the corresponding JSON Schema `type` (`string`,
79
+ * `number`, `integer`, `boolean`). Integer sub-types (int8 .. uint32)
80
+ * have their bounds described in `description` (Anthropic does not
81
+ * support `minimum`/`maximum`). `timestamp` becomes `string` with
82
+ * `format: "date-time"`.
83
+ * - **enum** -- mapped to `type: "string"` with an `enum` array.
84
+ * - **elements** -- mapped to `type: "array"` with `items`.
85
+ * - **properties / optionalProperties** -- mapped to `type: "object"` with
86
+ * `properties`, `required`, and `additionalProperties: false`. Unlike
87
+ * OpenAI, **optional properties are kept genuinely optional** -- they are
88
+ * not added to the `required` array. This avoids forced nullability.
89
+ * - **values** -- mapped to an array of `{key, value}` objects because
90
+ * Anthropic does not support `additionalProperties` with a schema value.
91
+ * During {@link convert}, the array is coerced back into a plain `Record`.
92
+ * - **discriminator** -- mapped to `anyOf` with one variant per mapping
93
+ * entry. Each variant is a flat object containing the discriminator key
94
+ * (with a `const` value) plus the variant's own properties.
95
+ *
96
+ * ### Unstructured schemas
97
+ * Empty JTD schemas or schemas with only `additionalProperties: true` are
98
+ * considered unstructured. They produce an empty `{}` JSON Schema with
99
+ * `strict: false`, and during {@link convert} the raw string output is
100
+ * parsed via `JSON.parse` back into an arbitrary value.
101
+ *
102
+ * ### MIME formats
103
+ * MIME signal formats become `type: "string"` with a description requesting
104
+ * base64-encoded content. On {@link convert}, the base64 string is decoded
105
+ * into a {@link ConvertSuccessBinary} result.
106
+ *
107
+ * ### Circular references
108
+ * Anthropic does not support recursive schemas. {@link fromJTD} will throw
109
+ * if any circular reference is detected among the JTD definitions.
110
+ *
111
+ * ### Serialization
112
+ * `JSON.stringify(conv)` produces a JSON-safe object via {@link toJSON}.
113
+ * Use {@link fromJSON} to restore a fully functional instance from the
114
+ * serialized form (string or parsed object).
115
+ *
116
+ * ```ts
117
+ * const conv = AnthropicConversion.fromJTD(jtdSchema);
118
+ * conv.schema; // Anthropic JSON Schema to pass to the LLM
119
+ * conv.strict; // whether strict mode applies
120
+ * conv.convert(output); // coerce + validate -> ConvertResult
45
121
  *
46
- * Handles single and multi-format signals:
47
- * - Single format: schema is the converted format directly.
48
- * - Multiple formats: wrapper object with genuinely optional `format_0`, `format_1`, etc.
122
+ * // Serialize & restore
123
+ * const cached = JSON.stringify(conv);
124
+ * const restored = AnthropicConversion.fromJSON(cached);
125
+ * ```
126
+ */
127
+ export declare class AnthropicConversion {
128
+ /** The Anthropic-specific JSON Schema to pass to the Anthropic API as the tool input schema. */
129
+ readonly schema: AnthropicSchema;
130
+ /**
131
+ * Whether the schema qualifies for Anthropic strict structured-output mode.
132
+ *
133
+ * This is `false` when the root JTD schema is empty or unstructured (e.g.
134
+ * the empty schema `{}` or a properties form with no real properties and
135
+ * `additionalProperties: true`). In that case `schema` is `{}` and the
136
+ * model output is unconstrained.
137
+ */
138
+ readonly strict: boolean;
139
+ /**
140
+ * The original JTD schema used to build this conversion.
141
+ * Set when created via {@link fromJTD}; `undefined` when created via {@link fromSignal}.
142
+ */
143
+ readonly jtdSchema?: JTDSchemaJson;
144
+ /**
145
+ * The original signal descriptor used to build this conversion.
146
+ * Set when created via {@link fromSignal}; `undefined` when created via {@link fromJTD}.
147
+ */
148
+ readonly descriptor?: SignalDescriptorJson;
149
+ /**
150
+ * Build a conversion from a JTD schema.
151
+ *
152
+ * Recursively converts every JTD form into the equivalent Anthropic JSON
153
+ * Schema node. Definitions (`jtdSchema.definitions`) are emitted as `$defs`
154
+ * at the root level, and references become `$ref` pointers.
155
+ *
156
+ * If the root schema is unstructured, the result has an empty `schema` and
157
+ * `strict: false`.
158
+ *
159
+ * @param jtdSchema - A valid JTD schema (RFC 8927).
160
+ * @returns A new {@link AnthropicConversion} with `jtdSchema` set.
161
+ * @throws If the schema contains an unknown JTD type, an unresolved `ref`,
162
+ * nesting exceeding 32 levels, or **any circular reference** among
163
+ * definitions (Anthropic does not support recursive schemas).
164
+ */
165
+ static fromJTD(jtdSchema: JTDSchemaJson): AnthropicConversion;
166
+ /**
167
+ * Build a conversion from an Adapt signal descriptor.
168
+ *
169
+ * If the descriptor has a single format, its schema is used directly
170
+ * (unwrapped). If it has multiple formats, a wrapper object schema is
171
+ * produced with `format_0`, `format_1`, ... properties. Unlike OpenAI,
172
+ * the format properties are genuinely optional (not listed in `required`),
173
+ * so the LLM only needs to provide the one it chooses.
174
+ *
175
+ * @param descriptor - An Adapt signal descriptor with one or more formats.
176
+ * @returns A new {@link AnthropicConversion} with `descriptor` set.
177
+ * @throws If the descriptor has no formats, or a format has neither
178
+ * `jtdSchema` nor `mimeType`.
179
+ */
180
+ static fromSignal(descriptor: SignalDescriptorJson): AnthropicConversion;
181
+ /**
182
+ * Restore an {@link AnthropicConversion} from its serialized form.
183
+ *
184
+ * Accepts either the JSON string produced by `JSON.stringify(conv)` or the
185
+ * already-parsed plain object. The original `jtdSchema` or `descriptor` is
186
+ * re-processed through the corresponding factory, so the restored instance
187
+ * is fully functional.
188
+ *
189
+ * @param data - A JSON string or parsed object previously produced by {@link toJSON}.
190
+ * @returns A fully reconstructed {@link AnthropicConversion}.
191
+ * @throws If the serialized data contains neither `jtdSchema` nor `descriptor`.
192
+ */
193
+ static fromJSON(data: string | Record<string, unknown>): AnthropicConversion;
194
+ private constructor();
195
+ /**
196
+ * Convert raw LLM output into a validated result.
197
+ *
198
+ * For JTD-based conversions, the value is coerced to conform to the original
199
+ * JTD schema:
200
+ * - Non-integer numbers are rounded for integer types.
201
+ * - `{key, value}` arrays from the values form are reassembled into Records.
202
+ * - Unstructured/empty schemas parse the raw JSON string via `JSON.parse`.
203
+ *
204
+ * Unlike OpenAI, no null-stripping is needed for optional properties because
205
+ * Anthropic keeps them genuinely optional (not in `required`).
206
+ *
207
+ * The coerced value is then validated against the JTD schema. Returns
208
+ * {@link ConvertSuccessJson} on success.
209
+ *
210
+ * For MIME-based conversions, the value is expected to be a base64 string
211
+ * which is decoded into raw bytes. Returns {@link ConvertSuccessBinary}.
212
+ *
213
+ * For multi-format signals, the first non-null `format_N` property is
214
+ * selected and converted individually.
215
+ *
216
+ * @param json - The raw value returned by the Anthropic API (typically parsed JSON).
217
+ * @returns A {@link ConvertResult} indicating success or failure with errors.
218
+ */
219
+ convert: (json: unknown) => ConvertResult;
220
+ /**
221
+ * Produce a JSON-serializable representation of this conversion.
222
+ *
223
+ * The output includes the Anthropic `schema`, `strict` flag, and either the
224
+ * original `jtdSchema` or `descriptor` (whichever was used to create this
225
+ * instance), which is sufficient to fully restore the conversion via
226
+ * {@link fromJSON}.
227
+ *
228
+ * Called automatically by `JSON.stringify(conv)`.
229
+ */
230
+ toJSON(): {
231
+ schema: AnthropicSchema;
232
+ strict: boolean;
233
+ descriptor: SignalDescriptorJson;
234
+ jtdSchema?: undefined;
235
+ } | {
236
+ schema: AnthropicSchema;
237
+ strict: boolean;
238
+ jtdSchema: JTDSchemaJson | undefined;
239
+ descriptor?: undefined;
240
+ };
241
+ }
242
+ /**
243
+ * Convenience alias for {@link AnthropicConversion.fromJTD}.
244
+ *
245
+ * @param jtdSchema - A valid JTD schema (RFC 8927).
246
+ * @returns A new {@link AnthropicConversion}.
247
+ */
248
+ export declare function convertToAnthropicSchema(jtdSchema: JTDSchemaJson): AnthropicConversion;
249
+ /**
250
+ * Convenience alias for {@link AnthropicConversion.fromSignal}.
49
251
  *
50
- * @throws {Error} if the descriptor has no formats.
252
+ * @param descriptor - An Adapt signal descriptor.
253
+ * @returns A new {@link AnthropicConversion}.
51
254
  */
52
- export declare function convertSignalToAnthropicSchema(descriptor: SignalDescriptorJson): AnthropicConversionResult;
255
+ export declare function convertSignalToAnthropicSchema(descriptor: SignalDescriptorJson): AnthropicConversion;
53
256
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/anthropic/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EAErB,MAAM,QAAQ,CAAC;AAOhB,mEAAmE;AACnE,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7C,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,oBAAoB,CAAC,EAAE,KAAK,CAAC;IAC7B,IAAI,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC;IAC5C,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,CAAC,EAAE,eAAe,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,KAAK,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,MAAM,aAAa,GAAG,cAAc,GAAG,cAAc,CAAC;AAE5D,MAAM,WAAW,yBAAyB;IACxC,0DAA0D;IAC1D,MAAM,EAAE,eAAe,CAAC;IACxB,uFAAuF;IACvF,MAAM,EAAE,OAAO,CAAC;IAChB,iEAAiE;IACjE,OAAO,EAAE,CAAC,aAAa,EAAE,OAAO,KAAK,aAAa,CAAC;CACpD;AA+lBD;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,aAAa,GACvB,yBAAyB,CA+C3B;AAqCD;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAC5C,UAAU,EAAE,oBAAoB,GAC/B,yBAAyB,CA8F3B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/anthropic/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EAErB,MAAM,QAAQ,CAAC;AAOhB;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7C,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,oBAAoB,CAAC,EAAE,KAAK,CAAC;IAC7B,IAAI,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC;IAC5C,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,CAAC,EAAE,eAAe,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,IAAI,EAAE,UAAU,CAAC;IACjB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,KAAK,CAAC;IACf,8EAA8E;IAC9E,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GACrB,kBAAkB,GAClB,oBAAoB,GACpB,cAAc,CAAC;AAslBnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,qBAAa,mBAAmB;IAC9B,gGAAgG;IAChG,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;IACnC;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAI3C;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,aAAa,GAAG,mBAAmB;IAmC7D;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,oBAAoB,GAAG,mBAAmB;IAKxE;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,mBAAmB;IAe5E,OAAO;IAcP;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,OAAO,GAAI,MAAM,OAAO,KAAG,aAAa,CAQtC;IAIF;;;;;;;;;OASG;IACH,MAAM;;;;;;;;;;;CAcP;AA4KD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,aAAa,GACvB,mBAAmB,CAErB;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,UAAU,EAAE,oBAAoB,GAC/B,mBAAmB,CAErB"}
@@ -1,2 +1,2 @@
1
- "use strict";var v=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var E=Object.prototype.hasOwnProperty;var N=(e,n)=>{for(var i in n)v(e,i,{get:n[i],enumerable:!0})},C=(e,n,i,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of x(n))!E.call(e,t)&&t!==i&&v(e,t,{get:()=>n[t],enumerable:!(o=P(n,t))||o.enumerable});return e};var I=e=>C(v({},"__esModule",{value:!0}),e);var W={};N(W,{convertSignalToAnthropicSchema:()=>L,convertToAnthropicSchema:()=>O});module.exports=I(W);var b=require("jtd");var M=new Set(["int8","uint8","int16","uint16","int32","uint32"]);function F(e){return e.length===0?"/":e.map(n=>/^\d+$/.test(n)?`[${n}]`:`.${n}`).join("")}function $(e,n){let i=e;for(let o=0;o<n.length-1&&(i&&typeof i=="object"&&n[o]in i);o++)i=i[n[o]];return i}function q(e,n){let i=e;for(let o of n)if(i&&typeof i=="object")i=i[o];else return;return i}function V(e,n,i){let{instancePath:o,schemaPath:t}=e,r=F(o),s=t[t.length-1];if(s==="type"){let c=$(n,t)?.type;return c==="boolean"?`${r}: expected boolean`:c==="string"?`${r}: expected string`:c==="timestamp"?`${r}: expected timestamp string`:M.has(c)?`${r}: expected integer`:`${r}: expected number`}if(s==="enum"){let c=$(n,t)?.enum;return`${r}: expected one of [${c.join(", ")}]`}if(t.length>=2&&t[t.length-2]==="properties"&&s)return`${r==="/"?"":r}.${s}: missing required property`;if(s==="elements")return`${r}: expected array`;if(s==="properties"||s==="optionalProperties"||s==="values")return`${r}: expected object`;if(s==="discriminator")return`${r}: expected string discriminator`;if(s==="mapping"){let a=q(i,o);return`${r}: unknown variant "${a}"`}return t.length===0?`${r}: unexpected property`:`${r}: validation error at /${t.join("/")}`}function k(e,n,i){let o=i??e.definitions,t=o?{...e,definitions:o}:e;return(0,b.isValidSchema)(t)?(0,b.validate)(t,n,{maxDepth:_,maxErrors:K}).map(s=>V(s,t,n)):e.ref?[`/: unknown ref "${e.ref}"`]:["/: invalid schema"]}var _=32,K=100;var h=32,R={int8:{minimum:-128,maximum:127},uint8:{minimum:0,maximum:255},int16:{minimum:-32768,maximum:32767},uint16:{minimum:0,maximum:65535},int32:{minimum:-2147483648,maximum:2147483647},uint32:{minimum:0,maximum:4294967295}},A={minimum:-34028235e31,maximum:34028235e31};function T(e){return!e||typeof e!="object"?!0:e.type||e.enum||e.elements||e.values||e.discriminator||e.ref||e.properties&&Object.keys(e.properties).length>0||e.optionalProperties&&Object.keys(e.optionalProperties).length>0?!1:(e.properties!==void 0||e.optionalProperties!==void 0)&&e.additionalProperties===!0?!0:!(e.properties!==void 0||e.optionalProperties!==void 0)}function H(e,n){let i=e,o=0;for(;i.ref&&o<h;){let t=n?.[i.ref];if(!t)return!1;i=t,o++}return o>=h?!1:T(i)}function S(e){let n=[];if(!e||typeof e!="object")return n;if(e.ref&&n.push(e.ref),e.properties)for(let i of Object.values(e.properties))n.push(...S(i));if(e.optionalProperties)for(let i of Object.values(e.optionalProperties))n.push(...S(i));if(e.elements&&n.push(...S(e.elements)),e.values&&n.push(...S(e.values)),e.mapping)for(let i of Object.values(e.mapping))n.push(...S(i));return n}function U(e){let t=new Map;for(let s of Object.keys(e))t.set(s,0);function r(s){t.set(s,1);let a=e[s];if(a){for(let c of S(a))if(t.has(c)){if(t.get(c)===1)return c;if(t.get(c)===0){let u=r(c);if(u)return u}}}return t.set(s,2),null}for(let s of Object.keys(e))if(t.get(s)===0){let a=r(s);if(a)return a}return null}function w(e,n){e.description=e.description?`${e.description} ${n}`:n}var B=new Set(["title","label","name","description"]);function f(e,n){let i=n.metadata;if(!i)return;let o=[],t=typeof i.title=="string"&&i.title.trim()||typeof i.label=="string"&&i.label.trim()||typeof i.name=="string"&&i.name.trim(),r=typeof i.description=="string"?i.description.trim():"";t&&r?o.push(`${t}. ${r}`):t?o.push(t):r&&o.push(r);let s=[];for(let[a,c]of Object.entries(i))B.has(a)||(typeof c=="string"&&c.trim()?s.push(`[${a}: ${c.trim()}]`):(typeof c=="number"||typeof c=="boolean")&&s.push(`[${a}: ${c}]`));if(s.length>0&&o.push(s.join(" ")),o.length>0){let a=o.join(" ");e.description=e.description?`${e.description} ${a}`:a}}function J(e,n,i){if(i>h)throw new Error(`Schema nesting exceeded ${h} levels`);if(!e||typeof e!="object")return{type:"string",description:"Must be a valid JSON value."};if(T(e)){let r={type:e.nullable===!0?["string","null"]:"string",description:"Must be a valid JSON value."};return f(r,e),r}let o=e.nullable===!0;if(e.ref){let t=e.ref;if(!n?.[t])throw new Error(`Unresolved ref "${t}"`);if(o){let r={anyOf:[{$ref:`#/$defs/${t}`},{type:"null"}]};return f(r,e),r}return{$ref:`#/$defs/${t}`}}if(e.type){let t=e.type,r={},s=R[t];if(s)return r.type=o?["integer","null"]:"integer",f(r,e),w(r,`Value range: [${s.minimum}, ${s.maximum}].`),r;switch(t){case"boolean":r.type=o?["boolean","null"]:"boolean";break;case"string":r.type=o?["string","null"]:"string";break;case"timestamp":r.type=o?["string","null"]:"string",r.format="date-time";break;case"float32":return r.type=o?["number","null"]:"number",f(r,e),w(r,`Value range: [${A.minimum}, ${A.maximum}].`),r;case"float64":r.type=o?["number","null"]:"number";break;default:throw new Error(`Unknown JTD type "${t}"`)}return f(r,e),r}if(e.enum){let t={type:o?["string","null"]:"string",enum:o?[...e.enum,null]:[...e.enum]};return f(t,e),t}if(e.elements){let t={type:o?["array","null"]:"array",items:J(e.elements,n,i+1)};return f(t,e),t}if(e.properties||e.optionalProperties){let t={type:o?["object","null"]:"object",properties:{},additionalProperties:!1},r=[];if(e.properties)for(let[s,a]of Object.entries(e.properties))t.properties[s]=J(a,n,i+1),r.push(s);if(e.optionalProperties)for(let[s,a]of Object.entries(e.optionalProperties))t.properties[s]=J(a,n,i+1);return r.length>0&&(t.required=r),f(t,e),t}if(e.values){let t=J(e.values,n,i+1),r={type:o?["array","null"]:"array",items:{type:"object",properties:{key:{type:"string"},value:t},required:["key","value"],additionalProperties:!1}};return f(r,e),r}if(e.discriminator&&e.mapping){let t=e.discriminator,r=e.mapping,s=[];for(let[c,u]of Object.entries(r)){let p;T(u)?p={type:"object",properties:{[t]:{const:c},_data:{type:"string",description:"Must be a valid JSON value representing the variant data."}},required:[t,"_data"],additionalProperties:!1}:(p=J(u,n,i+1),p.properties[t]={const:c},(p.required??=[]).unshift(t),p.additionalProperties=!1),f(p,u),s.push(p)}let a={anyOf:s};return o&&a.anyOf.push({type:"null"}),f(a,e),a}return{type:"string",description:"Must be a valid JSON value."}}var G=new Set(Object.keys(R));function g(e,n,i,o){if(o>h||e==null)return e;if(n.ref){let t=i?.[n.ref];return t?g(e,t,i,o+1):e}if(T(n)){if(typeof e=="string")try{return JSON.parse(e)}catch{return e}return e}if(n.type&&G.has(n.type))return typeof e=="number"&&!Number.isInteger(e)?Math.round(e):e;if(n.elements&&Array.isArray(e))return e.map(t=>g(t,n.elements,i,o+1));if((n.properties||n.optionalProperties)&&typeof e=="object"&&e!==null){let t={...e};if(n.properties)for(let[r,s]of Object.entries(n.properties))r in t&&(t[r]=g(t[r],s,i,o+1));if(n.optionalProperties)for(let[r,s]of Object.entries(n.optionalProperties))r in t&&(t[r]=g(t[r],s,i,o+1));return t}if(n.values&&Array.isArray(e)){let t={};for(let r of e)if(typeof r=="object"&&r!==null){let s=r,a=s.key;t[a]=g(s.value,n.values,i,o+1)}return t}if(n.discriminator&&n.mapping&&typeof e=="object"&&e!==null){let t=e,r=n.discriminator,s=t[r],a=n.mapping[s];if(!a)return e;if(T(a)){let u=t._data;if(typeof u=="string")try{let p=JSON.parse(u);if(typeof p=="object"&&p!==null)return{[r]:s,...p}}catch{}return{[r]:s}}let c={[r]:s};if(a.properties)for(let[u,p]of Object.entries(a.properties))u in t&&(c[u]=g(t[u],p,i,o+1));if(a.optionalProperties)for(let[u,p]of Object.entries(a.optionalProperties))u in t&&(c[u]=g(t[u],p,i,o+1));return c}return e}function O(e){let n=e.definitions;if(n&&Object.keys(n).length>0){let r=U(n);if(r)throw new Error(`Anthropic structured output does not support recursive schemas. Definition "${r}" contains a circular reference.`)}let i=!H(e,n),o;if(i){if(o=J(e,n,0),n&&Object.keys(n).length>0){let r={};for(let[s,a]of Object.entries(n))r[s]=J(a,n,0);o.$defs=r}}else o={},f(o,e);return{schema:o,strict:i,convert:r=>{let s=g(r,e,n,0),a=k(e,s,n);return a.length>0?{success:!1,errors:a}:{success:!0,data:s}}}}function Y(e){return{type:"string",description:`Base64-encoded binary content (MIME type: ${e}).`}}function j(e){if(e.jtdSchema)return O(e.jtdSchema);if(e.mimeType)return{schema:Y(e.mimeType),strict:!0,convert:o=>typeof o!="string"?{success:!1,errors:[`/: expected base64 string for MIME type ${e.mimeType}, got ${typeof o}`]}:{success:!0,data:o}};throw new Error("Signal format has neither jtdSchema nor mimeType")}function L(e){let n=e.formats;if(!n||n.length===0)throw new Error("Signal descriptor has no formats");let i=e.name??"unnamed",o=e.optional===!0;if(n.length===1){let l=j(n[0]);if(e.label||e.description){let m=[];e.label&&m.push(e.label),e.description&&m.push(e.description);let d=m.join(". ");l.schema.description=l.schema.description?`${d} ${l.schema.description}`:d}return l}let t=[],r={};for(let l=0;l<n.length;l++){let m=n[l],d=`format_${l}`,y=j(m);if(m.jtdSchema){let D=y.schema.description;y.schema.description=D?`Structured JSON data. ${D}`:"Structured JSON data."}r[d]=y.schema,t.push({key:d,converter:y})}let s=t.map(l=>l.key),a=e.description??"",c=o?"Provide at most ONE of the following format properties. All are optional.":`You MUST provide exactly ONE of the following format properties: ${s.join(", ")}.`;return{schema:{type:"object",description:a?`${a} ${c}`:c,properties:r,additionalProperties:!1},strict:!0,convert:l=>{if(typeof l!="object"||l===null)return{success:!1,errors:[`/: expected object with format properties, got ${typeof l}`]};let m=l,d=t.find(({key:y})=>m[y]!==void 0&&m[y]!==null);return d?d.converter.convert(m[d.key]):o?{success:!0,data:null}:{success:!1,errors:[`Signal '${i}' is required but no format was provided. Set exactly one of: ${s.join(", ")}.`]}}}}0&&(module.exports={convertSignalToAnthropicSchema,convertToAnthropicSchema});
1
+ "use strict";var J=Object.defineProperty;var O=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var x=Object.prototype.hasOwnProperty;var E=(e,t)=>{for(var n in t)J(e,n,{get:t[n],enumerable:!0})},N=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of P(t))!x.call(e,r)&&r!==n&&J(e,r,{get:()=>t[r],enumerable:!(o=O(t,r))||o.enumerable});return e};var C=e=>N(J({},"__esModule",{value:!0}),e);var te={};E(te,{AnthropicConversion:()=>y,convertSignalToAnthropicSchema:()=>ee,convertToAnthropicSchema:()=>Q});module.exports=C(te);var S=require("jtd");var I=new Set(["int8","uint8","int16","uint16","int32","uint32"]);function M(e){return e.length===0?"/":e.map(t=>/^\d+$/.test(t)?`[${t}]`:`.${t}`).join("")}function k(e,t){let n=e;for(let o=0;o<t.length-1&&(n&&typeof n=="object"&&t[o]in n);o++)n=n[t[o]];return n}function F(e,t){let n=e;for(let o of t)if(n&&typeof n=="object")n=n[o];else return;return n}function _(e,t,n){let{instancePath:o,schemaPath:r}=e,i=M(o),s=r[r.length-1];if(s==="type"){let c=k(t,r)?.type;return c==="boolean"?`${i}: expected boolean`:c==="string"?`${i}: expected string`:c==="timestamp"?`${i}: expected timestamp string`:I.has(c)?`${i}: expected integer`:`${i}: expected number`}if(s==="enum"){let c=k(t,r)?.enum;return`${i}: expected one of [${c.join(", ")}]`}if(r.length>=2&&r[r.length-2]==="properties"&&s)return`${i==="/"?"":i}.${s}: missing required property`;if(s==="elements")return`${i}: expected array`;if(s==="properties"||s==="optionalProperties"||s==="values")return`${i}: expected object`;if(s==="discriminator")return`${i}: expected string discriminator`;if(s==="mapping"){let a=F(n,o);return`${i}: unknown variant "${a}"`}return r.length===0?`${i}: unexpected property`:`${i}: validation error at /${r.join("/")}`}function D(e,t,n){let o=n??e.definitions,r=o?{...e,definitions:o}:e;return(0,S.isValidSchema)(r)?(0,S.validate)(r,t,{maxDepth:U,maxErrors:q}).map(s=>_(s,r,t)):e.ref?[`/: unknown ref "${e.ref}"`]:["/: invalid schema"]}var U=32,q=100;var h=32,T=`Must be a valid JSON value encoded as a string. For objects: '{"key": "value"}', for arrays: '[1, 2]', for primitives: '"hello"' or '42' or 'true' or 'null'.`,V=`The variant data encoded as a valid JSON string (e.g. '{"key": "value"}').`,B="Array of key-value entries representing a map/dictionary. Each entry has a string 'key' (the property name) and a 'value' (the property value).",j={int8:{minimum:-128,maximum:127},uint8:{minimum:0,maximum:255},int16:{minimum:-32768,maximum:32767},uint16:{minimum:0,maximum:65535},int32:{minimum:-2147483648,maximum:2147483647},uint32:{minimum:0,maximum:4294967295}},A={minimum:-34028235e31,maximum:34028235e31};function b(e){return!e||typeof e!="object"?!0:e.type||e.enum||e.elements||e.values||e.discriminator||e.ref||e.properties&&Object.keys(e.properties).length>0||e.optionalProperties&&Object.keys(e.optionalProperties).length>0?!1:(e.properties!==void 0||e.optionalProperties!==void 0)&&e.additionalProperties===!0?!0:!(e.properties!==void 0||e.optionalProperties!==void 0)}function K(e,t){let n=e,o=0;for(;n.ref&&o<h;){let r=t?.[n.ref];if(!r)return!1;n=r,o++}return o>=h?!1:b(n)}function g(e){let t=[];if(!e||typeof e!="object")return t;if(e.ref&&t.push(e.ref),e.properties)for(let n of Object.values(e.properties))t.push(...g(n));if(e.optionalProperties)for(let n of Object.values(e.optionalProperties))t.push(...g(n));if(e.elements&&t.push(...g(e.elements)),e.values&&t.push(...g(e.values)),e.mapping)for(let n of Object.values(e.mapping))t.push(...g(n));return t}function G(e){let r=new Map;for(let s of Object.keys(e))r.set(s,0);function i(s){r.set(s,1);let a=e[s];if(a){for(let c of g(a))if(r.has(c)){if(r.get(c)===1)return c;if(r.get(c)===0){let p=i(c);if(p)return p}}}return r.set(s,2),null}for(let s of Object.keys(e))if(r.get(s)===0){let a=i(s);if(a)return a}return null}function f(e,t){return t?[e,"null"]:e}function H(e,t){e.description=e.description?`${e.description} ${t}`:t}var Y=new Set(["title","label","name","description"]);function l(e,t){let n=t.metadata;if(!n)return;let o=[],r=typeof n.title=="string"&&n.title.trim()||typeof n.label=="string"&&n.label.trim()||typeof n.name=="string"&&n.name.trim(),i=typeof n.description=="string"?n.description.trim():"";r&&i?o.push(`${r}. ${i}`):r?o.push(r):i&&o.push(i);let s=[];for(let[a,c]of Object.entries(n))Y.has(a)||(typeof c=="string"&&c.trim()?s.push(`[${a}: ${c.trim()}]`):(typeof c=="number"||typeof c=="boolean")&&s.push(`[${a}: ${c}]`));if(s.length>0&&o.push(s.join(" ")),o.length>0){let a=o.join(" ");e.description=e.description?`${e.description} ${a}`:a}}function m(e,t,n){if(n>h)throw new Error(`Schema nesting exceeded ${h} levels`);if(!e||typeof e!="object")return{type:"string",description:T};if(b(e)){let r={type:f("string",e.nullable===!0),description:T};return l(r,e),r}let o=e.nullable===!0;if(e.ref){let r=e.ref;if(!t?.[r])throw new Error(`Unresolved ref "${r}"`);if(o){let i={anyOf:[{$ref:`#/$defs/${r}`},{type:"null"}]};return l(i,e),i}return{$ref:`#/$defs/${r}`}}if(e.type){let r={},i,s=j[e.type];if(s)r.type=f("integer",o),i=`Value range: [${s.minimum}, ${s.maximum}].`;else switch(e.type){case"boolean":r.type=f("boolean",o);break;case"string":r.type=f("string",o);break;case"timestamp":r.type=f("string",o),r.format="date-time";break;case"float32":r.type=f("number",o),i=`Value range: [${A.minimum}, ${A.maximum}].`;break;case"float64":r.type=f("number",o);break;default:throw new Error(`Unknown JTD type "${e.type}"`)}return l(r,e),i&&H(r,i),r}if(e.enum){let r={type:f("string",o),enum:o?[...e.enum,null]:e.enum};return l(r,e),r}if(e.elements){let r={type:f("array",o),items:m(e.elements,t,n+1)};return l(r,e),r}if(e.properties||e.optionalProperties){let r={},i=[];if(e.properties)for(let[a,c]of Object.entries(e.properties))r[a]=m(c,t,n+1),i.push(a);if(e.optionalProperties)for(let[a,c]of Object.entries(e.optionalProperties))r[a]=m(c,t,n+1);let s={type:f("object",o),properties:r,additionalProperties:!1};return i.length>0&&(s.required=i),l(s,e),s}if(e.values){let r=m(e.values,t,n+1),i={type:f("array",o),description:B,items:{type:"object",properties:{key:{type:"string",description:"The property name."},value:r},required:["key","value"],additionalProperties:!1}};return l(i,e),i}if(e.discriminator&&e.mapping){let r=e.discriminator,i=e.mapping,s=[];for(let[c,p]of Object.entries(i)){let u;b(p)?u={type:"object",properties:{[r]:{const:c},_data:{type:"string",description:V}},required:[r,"_data"],additionalProperties:!1}:(u=m(p,t,n+1),u.properties[r]={const:c},(u.required??=[]).unshift(r),u.additionalProperties=!1),l(u,p),s.push(u)}o&&s.push({type:"null"});let a={anyOf:s};return l(a,e),a}return{type:"string",description:T}}var L=new Set(Object.keys(j));function d(e,t,n,o){if(o>h||e==null)return e;if(t.ref){let r=n?.[t.ref];return r?d(e,r,n,o+1):e}if(b(t)){if(typeof e=="string")try{return JSON.parse(e)}catch{return e}return e}if(t.type&&L.has(t.type))return typeof e=="number"&&!Number.isInteger(e)?Math.round(e):e;if(t.elements&&Array.isArray(e)){let r=t.elements;return e.map(i=>d(i,r,n,o+1))}if((t.properties||t.optionalProperties)&&typeof e=="object"&&e!==null){let r={...e};if(t.properties)for(let[i,s]of Object.entries(t.properties))i in r&&(r[i]=d(r[i],s,n,o+1));if(t.optionalProperties)for(let[i,s]of Object.entries(t.optionalProperties))i in r&&(r[i]=d(r[i],s,n,o+1));return r}if(t.values&&Array.isArray(e)){let r={};for(let i of e)if(typeof i=="object"&&i!==null){let s=i,a=s.key;r[a]=d(s.value,t.values,n,o+1)}return r}if(t.discriminator&&t.mapping&&typeof e=="object"&&e!==null){let r=e,i=t.discriminator,s=r[i];if(typeof s!="string")return e;let a=t.mapping[s];if(!a)return e;if(b(a)){let p=r._data;if(typeof p=="string")try{let u=JSON.parse(p);if(typeof u=="object"&&u!==null)return{[i]:s,...u}}catch{}return{[i]:s}}let c={[i]:s};if(a.properties)for(let[p,u]of Object.entries(a.properties))p in r&&(c[p]=d(r[p],u,n,o+1));if(a.optionalProperties)for(let[p,u]of Object.entries(a.optionalProperties))p in r&&(c[p]=d(r[p],u,n,o+1));return c}return e}function W(e){return{type:"object",description:`Binary content (MIME type: ${e}).`,properties:{data:{type:"string",description:`The base64-encoded binary content (MIME type: ${e}).`},filename:{type:"string",description:'Optional filename for the binary content (e.g. "report.pdf", "image.png").'}},required:["data"],additionalProperties:!1}}var y=class e{schema;strict;jtdSchema;descriptor;static fromJTD(t){let n=t.definitions;if(n&&Object.keys(n).length>0){let i=G(n);if(i)throw new Error(`Anthropic structured output does not support recursive schemas. Definition "${i}" contains a circular reference.`)}let o=!K(t,n),r;return o?(r=m(t,n,0),n&&Object.keys(n).length>0&&(r.$defs=Object.fromEntries(Object.entries(n).map(([i,s])=>[i,m(s,n,0)])))):(r={},l(r,t)),new e(r,o,t,void 0)}static fromSignal(t){let{schema:n,strict:o}=Z(t);return new e(n,o,void 0,t)}static fromJSON(t){let n=typeof t=="string"?JSON.parse(t):t;if(n.descriptor)return e.fromSignal(n.descriptor);if(n.jtdSchema)return e.fromJTD(n.jtdSchema);throw new Error("Cannot deserialize: missing jtdSchema or descriptor")}constructor(t,n,o,r){this.schema=t,this.strict=n,this.jtdSchema=o,this.descriptor=r}convert=t=>this.jtdSchema?R(this.jtdSchema,t):this.descriptor?z(this.descriptor,t):{success:!1,errors:["No source schema available"]};toJSON(){return this.descriptor?{schema:this.schema,strict:this.strict,descriptor:this.descriptor}:{schema:this.schema,strict:this.strict,jtdSchema:this.jtdSchema}}};function R(e,t){let n=e.definitions,o=d(t,e,n,0),r=D(e,o,n);return r.length>0?{success:!1,errors:r}:{success:!0,kind:"json",data:o}}function X(e,t){if(typeof t!="object"||t===null)return{success:!1,errors:[`/: expected object with 'data' field for MIME type ${e}, got ${typeof t}`]};let n=t;if(typeof n.data!="string")return{success:!1,errors:[`/data: expected base64 string for MIME type ${e}, got ${typeof n.data}`]};let o={success:!0,kind:"binary",mimeType:e,data:new Uint8Array(Buffer.from(n.data,"base64"))};return typeof n.filename=="string"&&n.filename&&(o.filename=n.filename),o}function $(e,t){return e.mimeType?X(e.mimeType,t):e.jtdSchema?R(e.jtdSchema,t):{success:!1,errors:["Signal format has neither jtdSchema nor mimeType"]}}function z(e,t){let n=e.formats;if(!n||n.length===0)return{success:!1,errors:["Signal descriptor has no formats"]};if(n.length===1)return $(n[0],t);if(typeof t!="object"||t===null)return{success:!1,errors:[`/: expected object with format properties, got ${typeof t}`]};let o=t;for(let i=0;i<n.length;i++){let s=`format_${i}`;if(o[s]!==void 0&&o[s]!==null)return $(n[i],o[s])}if(e.optional)return{success:!0,kind:"json",data:null};let r=n.map((i,s)=>`format_${s}`);return{success:!1,errors:[`Signal '${e.name??"unnamed"}' is required but no format was provided. Set exactly one of: ${r.join(", ")}.`]}}function Z(e){let t=e.formats;if(!t||t.length===0)throw new Error("Signal descriptor has no formats");if(t.length===1){let[a]=t,{schema:c,strict:p}=w(a);if(e.label||e.description){let u=[];e.label&&u.push(e.label),e.description&&u.push(e.description);let v=u.join(". ");c.description=c.description?`${v} ${c.description}`:v}return{schema:c,strict:p}}let n={};for(let[a,c]of t.entries()){let{schema:p}=w(c);c.jtdSchema&&(p.description=p.description?`Structured JSON data. ${p.description}`:"Structured JSON data."),n[`format_${a}`]=p}let o=Object.keys(n),r=e.description??"",i=e.optional?"Provide at most ONE of the following format properties. All are optional.":`You MUST provide exactly ONE of the following format properties: ${o.join(", ")}.`;return{schema:{type:"object",description:r?`${r} ${i}`:i,properties:n,additionalProperties:!1},strict:!0}}function w(e){if(e.jtdSchema){let t=y.fromJTD(e.jtdSchema);return{schema:t.schema,strict:t.strict}}if(e.mimeType)return{schema:W(e.mimeType),strict:!0};throw new Error("Signal format has neither jtdSchema nor mimeType")}function Q(e){return y.fromJTD(e)}function ee(e){return y.fromSignal(e)}0&&(module.exports={AnthropicConversion,convertSignalToAnthropicSchema,convertToAnthropicSchema});
2
2
  //# sourceMappingURL=anthropic.cjs.map