@alint-js/plugin-js 0.0.28 → 0.0.29
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/S-CK_sYI4B.mjs +3796 -0
- package/dist/core-BMoyZMrf.mjs +788 -0
- package/dist/effect-Df2gY8Wx-sZLnuFMr.mjs +8 -0
- package/dist/esm-Dk08cWwM.mjs +4632 -0
- package/dist/esm-F2YJn-T8.mjs +111811 -0
- package/dist/index-DoHiaFQM-9scNuUlY.mjs +16 -0
- package/dist/index.d.mts +1848 -25
- package/dist/index.mjs +1683 -24
- package/dist/sury-BoOvxlMw-BFMqRCCo.mjs +8 -0
- package/dist/valibot-_ibN3zSD-p0SIbJDK.mjs +8 -0
- package/dist/zod-DjyNjMBF-G0rhiyEk.mjs +28 -0
- package/package.json +4 -3
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { n as strictJsonSchema } from "./index-DoHiaFQM-9scNuUlY.mjs";
|
|
2
|
+
import { t as __exportAll } from "./esm-F2YJn-T8.mjs";
|
|
3
|
+
import { setTimeout } from "node:timers/promises";
|
|
4
|
+
//#region ../plugin/dist/index.mjs
|
|
5
|
+
function definePlugin(plugin) {
|
|
6
|
+
return plugin;
|
|
7
|
+
}
|
|
8
|
+
function defineRule(rule) {
|
|
9
|
+
return rule;
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
4
12
|
//#region src/rules/inline-miniature-normalizer/prompt.ts
|
|
5
13
|
const inlineMiniatureNormalizerPrompt = `
|
|
6
14
|
You are reviewing one TypeScript file.
|
|
@@ -46,31 +54,1682 @@ Do not report:
|
|
|
46
54
|
Return warnings only. If uncertain, use medium or low confidence instead of forcing a finding.
|
|
47
55
|
`.trim();
|
|
48
56
|
//#endregion
|
|
57
|
+
//#region ../../node_modules/.pnpm/@moeru+std@0.1.0-beta.20/node_modules/@moeru/std/dist/error/index.js
|
|
58
|
+
const isError = (err) => {
|
|
59
|
+
if ("isError" in Error && Error.isError(new DOMException())) return Error.isError(err);
|
|
60
|
+
if (err === null || typeof err !== "object" && typeof err !== "function") return false;
|
|
61
|
+
if (err instanceof Error) return true;
|
|
62
|
+
const tag = Object.prototype.toString.call(err);
|
|
63
|
+
return tag === "[object DOMException]" || tag === "[object Error]";
|
|
64
|
+
};
|
|
65
|
+
const isErrorLike = (err) => {
|
|
66
|
+
if (isError(err)) return true;
|
|
67
|
+
if (err == null || typeof err !== "object" && typeof err !== "function") return false;
|
|
68
|
+
return "message" in err && typeof err.message === "string" && "name" in err && typeof err.name === "string";
|
|
69
|
+
};
|
|
70
|
+
const errorMessageFrom = (err) => isErrorLike(err) ? err.message : err == null ? void 0 : String(err);
|
|
71
|
+
const DEFAULT_CONFIG = {
|
|
72
|
+
lang: void 0,
|
|
73
|
+
message: void 0,
|
|
74
|
+
abortEarly: void 0,
|
|
75
|
+
abortPipeEarly: void 0
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Returns the global configuration.
|
|
79
|
+
*
|
|
80
|
+
* @param config The config to merge.
|
|
81
|
+
*
|
|
82
|
+
* @returns The configuration.
|
|
83
|
+
*/
|
|
84
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
85
|
+
function getGlobalConfig(config$1) {
|
|
86
|
+
if (!config$1 && true) return DEFAULT_CONFIG;
|
|
87
|
+
return {
|
|
88
|
+
lang: config$1?.lang ?? void 0,
|
|
89
|
+
message: config$1?.message,
|
|
90
|
+
abortEarly: config$1?.abortEarly ?? void 0,
|
|
91
|
+
abortPipeEarly: config$1?.abortPipeEarly ?? void 0
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Stringifies an unknown input to a literal or type string.
|
|
96
|
+
*
|
|
97
|
+
* @param input The unknown input.
|
|
98
|
+
*
|
|
99
|
+
* @returns A literal or type string.
|
|
100
|
+
*
|
|
101
|
+
* @internal
|
|
102
|
+
*/
|
|
103
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
104
|
+
function _stringify(input) {
|
|
105
|
+
const type = typeof input;
|
|
106
|
+
if (type === "string") return `"${input}"`;
|
|
107
|
+
if (type === "number" || type === "bigint" || type === "boolean") return `${input}`;
|
|
108
|
+
if (type === "object" || type === "function") return (input && Object.getPrototypeOf(input)?.constructor?.name) ?? "null";
|
|
109
|
+
return type;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Adds an issue to the dataset.
|
|
113
|
+
*
|
|
114
|
+
* @param context The issue context.
|
|
115
|
+
* @param label The issue label.
|
|
116
|
+
* @param dataset The input dataset.
|
|
117
|
+
* @param config The configuration.
|
|
118
|
+
* @param other The optional props.
|
|
119
|
+
*
|
|
120
|
+
* @internal
|
|
121
|
+
*/
|
|
122
|
+
function _addIssue(context, label, dataset, config$1, other) {
|
|
123
|
+
const input = other && "input" in other ? other.input : dataset.value;
|
|
124
|
+
const expected = other?.expected ?? context.expects ?? null;
|
|
125
|
+
const received = other?.received ?? /* @__PURE__ */ _stringify(input);
|
|
126
|
+
const issue = {
|
|
127
|
+
kind: context.kind,
|
|
128
|
+
type: context.type,
|
|
129
|
+
input,
|
|
130
|
+
expected,
|
|
131
|
+
received,
|
|
132
|
+
message: `Invalid ${label}: ${expected ? `Expected ${expected} but r` : "R"}eceived ${received}`,
|
|
133
|
+
requirement: context.requirement,
|
|
134
|
+
path: other?.path,
|
|
135
|
+
issues: other?.issues,
|
|
136
|
+
lang: config$1.lang,
|
|
137
|
+
abortEarly: config$1.abortEarly,
|
|
138
|
+
abortPipeEarly: config$1.abortPipeEarly
|
|
139
|
+
};
|
|
140
|
+
const isSchema = context.kind === "schema";
|
|
141
|
+
const message$1 = other?.message ?? context.message ?? (context.reference, issue.lang, void 0) ?? (isSchema ? (issue.lang, void 0) : null) ?? config$1.message ?? (issue.lang, void 0);
|
|
142
|
+
if (message$1 !== void 0) issue.message = typeof message$1 === "function" ? message$1(issue) : message$1;
|
|
143
|
+
if (isSchema) dataset.typed = false;
|
|
144
|
+
if (dataset.issues) dataset.issues.push(issue);
|
|
145
|
+
else dataset.issues = [issue];
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Returns the last top-level value of a given metadata type from a schema
|
|
149
|
+
* using a breadth-first search that starts with the last item in the pipeline.
|
|
150
|
+
*
|
|
151
|
+
* @param schema The schema to search.
|
|
152
|
+
* @param type The metadata type.
|
|
153
|
+
*
|
|
154
|
+
* @returns The value, if any.
|
|
155
|
+
*
|
|
156
|
+
* @internal
|
|
157
|
+
*/
|
|
158
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
159
|
+
function _getLastMetadata(schema, type) {
|
|
160
|
+
if ("pipe" in schema) {
|
|
161
|
+
const nestedSchemas = [];
|
|
162
|
+
for (let index = schema.pipe.length - 1; index >= 0; index--) {
|
|
163
|
+
const item = schema.pipe[index];
|
|
164
|
+
if (item.kind === "schema" && "pipe" in item) nestedSchemas.push(item);
|
|
165
|
+
else if (item.kind === "metadata" && item.type === type) return item[type];
|
|
166
|
+
}
|
|
167
|
+
for (const nestedSchema of nestedSchemas) {
|
|
168
|
+
const result = /* @__PURE__ */ _getLastMetadata(nestedSchema, type);
|
|
169
|
+
if (result !== void 0) return result;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const _standardCache = /* @__PURE__ */ new WeakMap();
|
|
174
|
+
/**
|
|
175
|
+
* Returns the Standard Schema properties.
|
|
176
|
+
*
|
|
177
|
+
* @param context The schema context.
|
|
178
|
+
*
|
|
179
|
+
* @returns The Standard Schema properties.
|
|
180
|
+
*/
|
|
181
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
182
|
+
function _getStandardProps(context) {
|
|
183
|
+
let cached = _standardCache.get(context);
|
|
184
|
+
if (!cached) {
|
|
185
|
+
cached = {
|
|
186
|
+
version: 1,
|
|
187
|
+
vendor: "valibot",
|
|
188
|
+
validate(value$1) {
|
|
189
|
+
return context["~run"]({ value: value$1 }, /* @__PURE__ */ getGlobalConfig());
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
_standardCache.set(context, cached);
|
|
193
|
+
}
|
|
194
|
+
return cached;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Joins multiple `expects` values with the given separator.
|
|
198
|
+
*
|
|
199
|
+
* @param values The `expects` values.
|
|
200
|
+
* @param separator The separator.
|
|
201
|
+
*
|
|
202
|
+
* @returns The joined `expects` property.
|
|
203
|
+
*
|
|
204
|
+
* @internal
|
|
205
|
+
*/
|
|
206
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
207
|
+
function _joinExpects(values$1, separator) {
|
|
208
|
+
const list = [...new Set(values$1)];
|
|
209
|
+
if (list.length > 1) return `(${list.join(` ${separator} `)})`;
|
|
210
|
+
return list[0] ?? "never";
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* A Valibot error with useful information.
|
|
214
|
+
*/
|
|
215
|
+
var ValiError = class extends Error {
|
|
216
|
+
/**
|
|
217
|
+
* Creates a Valibot error with useful information.
|
|
218
|
+
*
|
|
219
|
+
* @param issues The error issues.
|
|
220
|
+
*/
|
|
221
|
+
constructor(issues) {
|
|
222
|
+
super(issues[0].message);
|
|
223
|
+
this.name = "ValiError";
|
|
224
|
+
this.issues = issues;
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
/**
|
|
228
|
+
* Creates a description metadata action.
|
|
229
|
+
*
|
|
230
|
+
* @param description_ The description text.
|
|
231
|
+
*
|
|
232
|
+
* @returns A description action.
|
|
233
|
+
*/
|
|
234
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
235
|
+
function description(description_) {
|
|
236
|
+
return {
|
|
237
|
+
kind: "metadata",
|
|
238
|
+
type: "description",
|
|
239
|
+
reference: description,
|
|
240
|
+
description: description_
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Returns the fallback value of the schema.
|
|
245
|
+
*
|
|
246
|
+
* @param schema The schema to get it from.
|
|
247
|
+
* @param dataset The output dataset if available.
|
|
248
|
+
* @param config The config if available.
|
|
249
|
+
*
|
|
250
|
+
* @returns The fallback value.
|
|
251
|
+
*/
|
|
252
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
253
|
+
function getFallback(schema, dataset, config$1) {
|
|
254
|
+
return typeof schema.fallback === "function" ? schema.fallback(dataset, config$1) : schema.fallback;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Returns the default value of the schema.
|
|
258
|
+
*
|
|
259
|
+
* @param schema The schema to get it from.
|
|
260
|
+
* @param dataset The input dataset if available.
|
|
261
|
+
* @param config The config if available.
|
|
262
|
+
*
|
|
263
|
+
* @returns The default value.
|
|
264
|
+
*/
|
|
265
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
266
|
+
function getDefault(schema, dataset, config$1) {
|
|
267
|
+
return typeof schema.default === "function" ? schema.default(dataset, config$1) : schema.default;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Returns the description of the schema.
|
|
271
|
+
*
|
|
272
|
+
* If multiple descriptions are defined, the last one of the highest level is
|
|
273
|
+
* returned. If no description is defined, `undefined` is returned.
|
|
274
|
+
*
|
|
275
|
+
* @param schema The schema to get the description from.
|
|
276
|
+
*
|
|
277
|
+
* @returns The description, if any.
|
|
278
|
+
*
|
|
279
|
+
* @beta
|
|
280
|
+
*/
|
|
281
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
282
|
+
function getDescription(schema) {
|
|
283
|
+
return /* @__PURE__ */ _getLastMetadata(schema, "description");
|
|
284
|
+
}
|
|
285
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
286
|
+
function array(item, message$1) {
|
|
287
|
+
return {
|
|
288
|
+
kind: "schema",
|
|
289
|
+
type: "array",
|
|
290
|
+
reference: array,
|
|
291
|
+
expects: "Array",
|
|
292
|
+
async: false,
|
|
293
|
+
item,
|
|
294
|
+
message: message$1,
|
|
295
|
+
get "~standard"() {
|
|
296
|
+
return /* @__PURE__ */ _getStandardProps(this);
|
|
297
|
+
},
|
|
298
|
+
"~run"(dataset, config$1) {
|
|
299
|
+
const input = dataset.value;
|
|
300
|
+
if (Array.isArray(input)) {
|
|
301
|
+
dataset.typed = true;
|
|
302
|
+
dataset.value = [];
|
|
303
|
+
for (let key = 0; key < input.length; key++) {
|
|
304
|
+
const value$1 = input[key];
|
|
305
|
+
const itemDataset = this.item["~run"]({ value: value$1 }, config$1);
|
|
306
|
+
if (itemDataset.issues) {
|
|
307
|
+
const pathItem = {
|
|
308
|
+
type: "array",
|
|
309
|
+
origin: "value",
|
|
310
|
+
input,
|
|
311
|
+
key,
|
|
312
|
+
value: value$1
|
|
313
|
+
};
|
|
314
|
+
for (const issue of itemDataset.issues) {
|
|
315
|
+
if (issue.path) issue.path.unshift(pathItem);
|
|
316
|
+
else issue.path = [pathItem];
|
|
317
|
+
dataset.issues?.push(issue);
|
|
318
|
+
}
|
|
319
|
+
if (!dataset.issues) dataset.issues = itemDataset.issues;
|
|
320
|
+
if (config$1.abortEarly) {
|
|
321
|
+
dataset.typed = false;
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
if (!itemDataset.typed) dataset.typed = false;
|
|
326
|
+
dataset.value.push(itemDataset.value);
|
|
327
|
+
}
|
|
328
|
+
} else _addIssue(this, "type", dataset, config$1);
|
|
329
|
+
return dataset;
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
334
|
+
function boolean(message$1) {
|
|
335
|
+
return {
|
|
336
|
+
kind: "schema",
|
|
337
|
+
type: "boolean",
|
|
338
|
+
reference: boolean,
|
|
339
|
+
expects: "boolean",
|
|
340
|
+
async: false,
|
|
341
|
+
message: message$1,
|
|
342
|
+
get "~standard"() {
|
|
343
|
+
return /* @__PURE__ */ _getStandardProps(this);
|
|
344
|
+
},
|
|
345
|
+
"~run"(dataset, config$1) {
|
|
346
|
+
if (typeof dataset.value === "boolean") dataset.typed = true;
|
|
347
|
+
else _addIssue(this, "type", dataset, config$1);
|
|
348
|
+
return dataset;
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
353
|
+
function number(message$1) {
|
|
354
|
+
return {
|
|
355
|
+
kind: "schema",
|
|
356
|
+
type: "number",
|
|
357
|
+
reference: number,
|
|
358
|
+
expects: "number",
|
|
359
|
+
async: false,
|
|
360
|
+
message: message$1,
|
|
361
|
+
get "~standard"() {
|
|
362
|
+
return /* @__PURE__ */ _getStandardProps(this);
|
|
363
|
+
},
|
|
364
|
+
"~run"(dataset, config$1) {
|
|
365
|
+
if (typeof dataset.value === "number" && !isNaN(dataset.value)) dataset.typed = true;
|
|
366
|
+
else _addIssue(this, "type", dataset, config$1);
|
|
367
|
+
return dataset;
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
372
|
+
function object(entries$1, message$1) {
|
|
373
|
+
return {
|
|
374
|
+
kind: "schema",
|
|
375
|
+
type: "object",
|
|
376
|
+
reference: object,
|
|
377
|
+
expects: "Object",
|
|
378
|
+
async: false,
|
|
379
|
+
entries: entries$1,
|
|
380
|
+
message: message$1,
|
|
381
|
+
get "~standard"() {
|
|
382
|
+
return /* @__PURE__ */ _getStandardProps(this);
|
|
383
|
+
},
|
|
384
|
+
"~run"(dataset, config$1) {
|
|
385
|
+
const input = dataset.value;
|
|
386
|
+
if (input && typeof input === "object") {
|
|
387
|
+
dataset.typed = true;
|
|
388
|
+
dataset.value = {};
|
|
389
|
+
for (const key in this.entries) {
|
|
390
|
+
const valueSchema = this.entries[key];
|
|
391
|
+
if (key in input || (valueSchema.type === "exact_optional" || valueSchema.type === "optional" || valueSchema.type === "nullish") && valueSchema.default !== void 0) {
|
|
392
|
+
const value$1 = key in input ? input[key] : /* @__PURE__ */ getDefault(valueSchema);
|
|
393
|
+
const valueDataset = valueSchema["~run"]({ value: value$1 }, config$1);
|
|
394
|
+
if (valueDataset.issues) {
|
|
395
|
+
const pathItem = {
|
|
396
|
+
type: "object",
|
|
397
|
+
origin: "value",
|
|
398
|
+
input,
|
|
399
|
+
key,
|
|
400
|
+
value: value$1
|
|
401
|
+
};
|
|
402
|
+
for (const issue of valueDataset.issues) {
|
|
403
|
+
if (issue.path) issue.path.unshift(pathItem);
|
|
404
|
+
else issue.path = [pathItem];
|
|
405
|
+
dataset.issues?.push(issue);
|
|
406
|
+
}
|
|
407
|
+
if (!dataset.issues) dataset.issues = valueDataset.issues;
|
|
408
|
+
if (config$1.abortEarly) {
|
|
409
|
+
dataset.typed = false;
|
|
410
|
+
break;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
if (!valueDataset.typed) dataset.typed = false;
|
|
414
|
+
dataset.value[key] = valueDataset.value;
|
|
415
|
+
} else if (valueSchema.fallback !== void 0) dataset.value[key] = /* @__PURE__ */ getFallback(valueSchema);
|
|
416
|
+
else if (valueSchema.type !== "exact_optional" && valueSchema.type !== "optional" && valueSchema.type !== "nullish") {
|
|
417
|
+
_addIssue(this, "key", dataset, config$1, {
|
|
418
|
+
input: void 0,
|
|
419
|
+
expected: `"${key}"`,
|
|
420
|
+
path: [{
|
|
421
|
+
type: "object",
|
|
422
|
+
origin: "key",
|
|
423
|
+
input,
|
|
424
|
+
key,
|
|
425
|
+
value: input[key]
|
|
426
|
+
}]
|
|
427
|
+
});
|
|
428
|
+
if (config$1.abortEarly) break;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
} else _addIssue(this, "type", dataset, config$1);
|
|
432
|
+
return dataset;
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
437
|
+
function picklist(options, message$1) {
|
|
438
|
+
return {
|
|
439
|
+
kind: "schema",
|
|
440
|
+
type: "picklist",
|
|
441
|
+
reference: picklist,
|
|
442
|
+
expects: /* @__PURE__ */ _joinExpects(options.map(_stringify), "|"),
|
|
443
|
+
async: false,
|
|
444
|
+
options,
|
|
445
|
+
message: message$1,
|
|
446
|
+
get "~standard"() {
|
|
447
|
+
return /* @__PURE__ */ _getStandardProps(this);
|
|
448
|
+
},
|
|
449
|
+
"~run"(dataset, config$1) {
|
|
450
|
+
if (this.options.includes(dataset.value)) dataset.typed = true;
|
|
451
|
+
else _addIssue(this, "type", dataset, config$1);
|
|
452
|
+
return dataset;
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
457
|
+
function string(message$1) {
|
|
458
|
+
return {
|
|
459
|
+
kind: "schema",
|
|
460
|
+
type: "string",
|
|
461
|
+
reference: string,
|
|
462
|
+
expects: "string",
|
|
463
|
+
async: false,
|
|
464
|
+
message: message$1,
|
|
465
|
+
get "~standard"() {
|
|
466
|
+
return /* @__PURE__ */ _getStandardProps(this);
|
|
467
|
+
},
|
|
468
|
+
"~run"(dataset, config$1) {
|
|
469
|
+
if (typeof dataset.value === "string") dataset.typed = true;
|
|
470
|
+
else _addIssue(this, "type", dataset, config$1);
|
|
471
|
+
return dataset;
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Parses an unknown input based on a schema.
|
|
477
|
+
*
|
|
478
|
+
* @param schema The schema to be used.
|
|
479
|
+
* @param input The input to be parsed.
|
|
480
|
+
* @param config The parse configuration.
|
|
481
|
+
*
|
|
482
|
+
* @returns The parsed input.
|
|
483
|
+
*/
|
|
484
|
+
function parse(schema, input, config$1) {
|
|
485
|
+
const dataset = schema["~run"]({ value: input }, /* @__PURE__ */ getGlobalConfig(config$1));
|
|
486
|
+
if (dataset.issues) throw new ValiError(dataset.issues);
|
|
487
|
+
return dataset.value;
|
|
488
|
+
}
|
|
489
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
490
|
+
function pipe(...pipe$1) {
|
|
491
|
+
return {
|
|
492
|
+
...pipe$1[0],
|
|
493
|
+
pipe: pipe$1,
|
|
494
|
+
get "~standard"() {
|
|
495
|
+
return /* @__PURE__ */ _getStandardProps(this);
|
|
496
|
+
},
|
|
497
|
+
"~run"(dataset, config$1) {
|
|
498
|
+
for (const item of pipe$1) if (item.kind !== "metadata") {
|
|
499
|
+
if (dataset.issues && (item.kind === "schema" || item.kind === "transformation")) {
|
|
500
|
+
dataset.typed = false;
|
|
501
|
+
break;
|
|
502
|
+
}
|
|
503
|
+
if (!dataset.issues || !config$1.abortEarly && !config$1.abortPipeEarly) dataset = item["~run"](dataset, config$1);
|
|
504
|
+
}
|
|
505
|
+
return dataset;
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
//#endregion
|
|
510
|
+
//#region ../../node_modules/.pnpm/@valibot+to-json-schema@1.7.1_valibot@1.4.2_typescript@6.0.3_/node_modules/@valibot/to-json-schema/dist/index.mjs
|
|
511
|
+
var dist_exports = /* @__PURE__ */ __exportAll({
|
|
512
|
+
addGlobalDefs: () => addGlobalDefs,
|
|
513
|
+
getGlobalDefs: () => getGlobalDefs,
|
|
514
|
+
toJsonSchema: () => toJsonSchema,
|
|
515
|
+
toJsonSchemaDefs: () => toJsonSchemaDefs,
|
|
516
|
+
toStandardJsonSchema: () => toStandardJsonSchema
|
|
517
|
+
});
|
|
518
|
+
/**
|
|
519
|
+
* Adds an error message to the errors array.
|
|
520
|
+
*
|
|
521
|
+
* @param errors The array of error messages.
|
|
522
|
+
* @param message The error message to add.
|
|
523
|
+
*
|
|
524
|
+
* @returns The new errors.
|
|
525
|
+
*/
|
|
526
|
+
function addError(errors, message) {
|
|
527
|
+
if (errors) {
|
|
528
|
+
errors.push(message);
|
|
529
|
+
return errors;
|
|
530
|
+
}
|
|
531
|
+
return [message];
|
|
532
|
+
}
|
|
533
|
+
const ESCAPE_REGEX = /[.*+?^${}()|[\]\\]/g;
|
|
534
|
+
/**
|
|
535
|
+
* Escapes special regex characters in a string.
|
|
536
|
+
*
|
|
537
|
+
* @param string The string to escape.
|
|
538
|
+
*
|
|
539
|
+
* @returns The escaped string.
|
|
540
|
+
*/
|
|
541
|
+
function escapeRegExp(string) {
|
|
542
|
+
return string.replace(ESCAPE_REGEX, "\\$&");
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Throws an error or logs a warning based on the configuration.
|
|
546
|
+
*
|
|
547
|
+
* @param message The message to throw or log.
|
|
548
|
+
* @param config The conversion configuration.
|
|
549
|
+
*/
|
|
550
|
+
function handleError(message, config) {
|
|
551
|
+
switch (config?.errorMode) {
|
|
552
|
+
case "ignore": break;
|
|
553
|
+
case "warn":
|
|
554
|
+
console.warn(message);
|
|
555
|
+
break;
|
|
556
|
+
default: throw new Error(message);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Whether a value is JSON compatible for a const keyword.
|
|
561
|
+
*
|
|
562
|
+
* @param value The value to check.
|
|
563
|
+
*
|
|
564
|
+
* @returns Whether the value is JSON compatible.
|
|
565
|
+
*/
|
|
566
|
+
function isJsonConstValue(value) {
|
|
567
|
+
return typeof value === "boolean" || typeof value === "number" && Number.isFinite(value) || typeof value === "string";
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Whether values are JSON compatible for an enum keyword.
|
|
571
|
+
*
|
|
572
|
+
* @param values The values to check.
|
|
573
|
+
*
|
|
574
|
+
* @returns Whether the values are JSON compatible.
|
|
575
|
+
*/
|
|
576
|
+
function isJsonEnumValues(values) {
|
|
577
|
+
return values.every(isJsonConstValue);
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Converts any supported Valibot action to the JSON Schema format.
|
|
581
|
+
*
|
|
582
|
+
* @param jsonSchema The JSON Schema object.
|
|
583
|
+
* @param valibotAction The Valibot action object.
|
|
584
|
+
* @param config The conversion configuration.
|
|
585
|
+
*
|
|
586
|
+
* @returns The converted JSON Schema.
|
|
587
|
+
*/
|
|
588
|
+
function convertAction(jsonSchema, valibotAction, config) {
|
|
589
|
+
if (config?.ignoreActions?.includes(valibotAction.type)) return jsonSchema;
|
|
590
|
+
let errors;
|
|
591
|
+
switch (valibotAction.type) {
|
|
592
|
+
case "base64":
|
|
593
|
+
jsonSchema.contentEncoding = "base64";
|
|
594
|
+
break;
|
|
595
|
+
case "bic":
|
|
596
|
+
case "cuid2":
|
|
597
|
+
case "decimal":
|
|
598
|
+
case "digits":
|
|
599
|
+
case "domain":
|
|
600
|
+
case "emoji":
|
|
601
|
+
case "hash":
|
|
602
|
+
case "hexadecimal":
|
|
603
|
+
case "hex_color":
|
|
604
|
+
case "isrc":
|
|
605
|
+
case "iso_time_second":
|
|
606
|
+
case "iso_week":
|
|
607
|
+
case "mac":
|
|
608
|
+
case "mac48":
|
|
609
|
+
case "mac64":
|
|
610
|
+
case "nanoid":
|
|
611
|
+
case "octal":
|
|
612
|
+
case "slug":
|
|
613
|
+
case "ulid":
|
|
614
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
615
|
+
else jsonSchema.pattern = valibotAction.requirement.source;
|
|
616
|
+
break;
|
|
617
|
+
case "description":
|
|
618
|
+
jsonSchema.description = valibotAction.description;
|
|
619
|
+
break;
|
|
620
|
+
case "email":
|
|
621
|
+
case "rfc_email":
|
|
622
|
+
jsonSchema.format = "email";
|
|
623
|
+
break;
|
|
624
|
+
case "ends_with":
|
|
625
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
626
|
+
else jsonSchema.pattern = `${escapeRegExp(valibotAction.requirement)}$`;
|
|
627
|
+
break;
|
|
628
|
+
case "empty":
|
|
629
|
+
if (jsonSchema.type === "array") jsonSchema.maxItems = 0;
|
|
630
|
+
else {
|
|
631
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
632
|
+
jsonSchema.maxLength = 0;
|
|
633
|
+
}
|
|
634
|
+
break;
|
|
635
|
+
case "entries":
|
|
636
|
+
jsonSchema.minProperties = valibotAction.requirement;
|
|
637
|
+
jsonSchema.maxProperties = valibotAction.requirement;
|
|
638
|
+
break;
|
|
639
|
+
case "examples":
|
|
640
|
+
if (Array.isArray(jsonSchema.examples)) jsonSchema.examples = [...jsonSchema.examples, ...valibotAction.examples];
|
|
641
|
+
else jsonSchema.examples = valibotAction.examples;
|
|
642
|
+
break;
|
|
643
|
+
case "gt_value":
|
|
644
|
+
if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") errors = addError(errors, `The "gt_value" action is not supported on type "${jsonSchema.type}".`);
|
|
645
|
+
if (config?.target === "openapi-3.0") {
|
|
646
|
+
errors = addError(errors, "The \"gt_value\" action is not supported for OpenAPI 3.0.");
|
|
647
|
+
break;
|
|
648
|
+
}
|
|
649
|
+
jsonSchema.exclusiveMinimum = valibotAction.requirement;
|
|
650
|
+
break;
|
|
651
|
+
case "includes":
|
|
652
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
653
|
+
else jsonSchema.pattern = escapeRegExp(valibotAction.requirement);
|
|
654
|
+
break;
|
|
655
|
+
case "integer":
|
|
656
|
+
jsonSchema.type = "integer";
|
|
657
|
+
break;
|
|
658
|
+
case "ipv4":
|
|
659
|
+
jsonSchema.format = "ipv4";
|
|
660
|
+
break;
|
|
661
|
+
case "ipv6":
|
|
662
|
+
jsonSchema.format = "ipv6";
|
|
663
|
+
break;
|
|
664
|
+
case "iso_date":
|
|
665
|
+
jsonSchema.format = "date";
|
|
666
|
+
break;
|
|
667
|
+
case "iso_date_time":
|
|
668
|
+
case "iso_timestamp":
|
|
669
|
+
jsonSchema.format = "date-time";
|
|
670
|
+
break;
|
|
671
|
+
case "iso_time":
|
|
672
|
+
jsonSchema.format = "time";
|
|
673
|
+
break;
|
|
674
|
+
case "jws_compact":
|
|
675
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
676
|
+
else jsonSchema.pattern = valibotAction.requirement.source;
|
|
677
|
+
break;
|
|
678
|
+
case "length":
|
|
679
|
+
if (jsonSchema.type === "array") {
|
|
680
|
+
jsonSchema.minItems = valibotAction.requirement;
|
|
681
|
+
jsonSchema.maxItems = valibotAction.requirement;
|
|
682
|
+
} else {
|
|
683
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
684
|
+
jsonSchema.minLength = valibotAction.requirement;
|
|
685
|
+
jsonSchema.maxLength = valibotAction.requirement;
|
|
686
|
+
}
|
|
687
|
+
break;
|
|
688
|
+
case "lt_value":
|
|
689
|
+
if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") errors = addError(errors, `The "lt_value" action is not supported on type "${jsonSchema.type}".`);
|
|
690
|
+
if (config?.target === "openapi-3.0") {
|
|
691
|
+
errors = addError(errors, "The \"lt_value\" action is not supported for OpenAPI 3.0.");
|
|
692
|
+
break;
|
|
693
|
+
}
|
|
694
|
+
jsonSchema.exclusiveMaximum = valibotAction.requirement;
|
|
695
|
+
break;
|
|
696
|
+
case "max_entries":
|
|
697
|
+
jsonSchema.maxProperties = valibotAction.requirement;
|
|
698
|
+
break;
|
|
699
|
+
case "max_length":
|
|
700
|
+
if (jsonSchema.type === "array") jsonSchema.maxItems = valibotAction.requirement;
|
|
701
|
+
else {
|
|
702
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
703
|
+
jsonSchema.maxLength = valibotAction.requirement;
|
|
704
|
+
}
|
|
705
|
+
break;
|
|
706
|
+
case "max_value":
|
|
707
|
+
if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") errors = addError(errors, `The "max_value" action is not supported on type "${jsonSchema.type}".`);
|
|
708
|
+
jsonSchema.maximum = valibotAction.requirement;
|
|
709
|
+
break;
|
|
710
|
+
case "metadata":
|
|
711
|
+
if (typeof valibotAction.metadata.title === "string") jsonSchema.title = valibotAction.metadata.title;
|
|
712
|
+
if (typeof valibotAction.metadata.description === "string") jsonSchema.description = valibotAction.metadata.description;
|
|
713
|
+
if (Array.isArray(valibotAction.metadata.examples)) if (Array.isArray(jsonSchema.examples)) jsonSchema.examples = [...jsonSchema.examples, ...valibotAction.metadata.examples];
|
|
714
|
+
else jsonSchema.examples = valibotAction.metadata.examples;
|
|
715
|
+
break;
|
|
716
|
+
case "min_entries":
|
|
717
|
+
jsonSchema.minProperties = valibotAction.requirement;
|
|
718
|
+
break;
|
|
719
|
+
case "min_length":
|
|
720
|
+
if (jsonSchema.type === "array") jsonSchema.minItems = valibotAction.requirement;
|
|
721
|
+
else {
|
|
722
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
723
|
+
jsonSchema.minLength = valibotAction.requirement;
|
|
724
|
+
}
|
|
725
|
+
break;
|
|
726
|
+
case "min_value":
|
|
727
|
+
if (jsonSchema.type !== "number" && jsonSchema.type !== "integer") errors = addError(errors, `The "min_value" action is not supported on type "${jsonSchema.type}".`);
|
|
728
|
+
jsonSchema.minimum = valibotAction.requirement;
|
|
729
|
+
break;
|
|
730
|
+
case "multiple_of":
|
|
731
|
+
jsonSchema.multipleOf = valibotAction.requirement;
|
|
732
|
+
break;
|
|
733
|
+
case "non_empty":
|
|
734
|
+
if (jsonSchema.type === "array") jsonSchema.minItems = 1;
|
|
735
|
+
else {
|
|
736
|
+
if (jsonSchema.type !== "string") errors = addError(errors, `The "${valibotAction.type}" action is not supported on type "${jsonSchema.type}".`);
|
|
737
|
+
jsonSchema.minLength = 1;
|
|
738
|
+
}
|
|
739
|
+
break;
|
|
740
|
+
case "not_value":
|
|
741
|
+
if (!isJsonConstValue(valibotAction.requirement)) {
|
|
742
|
+
errors = addError(errors, "The requirement of the \"not_value\" action is not JSON compatible.");
|
|
743
|
+
break;
|
|
744
|
+
}
|
|
745
|
+
if (config?.target === "openapi-3.0") jsonSchema.not = { enum: [valibotAction.requirement] };
|
|
746
|
+
else jsonSchema.not = { const: valibotAction.requirement };
|
|
747
|
+
break;
|
|
748
|
+
case "not_values":
|
|
749
|
+
if (!isJsonEnumValues(valibotAction.requirement)) {
|
|
750
|
+
errors = addError(errors, "A requirement of the \"not_values\" action is not JSON compatible.");
|
|
751
|
+
break;
|
|
752
|
+
}
|
|
753
|
+
jsonSchema.not = { enum: valibotAction.requirement };
|
|
754
|
+
break;
|
|
755
|
+
case "regex":
|
|
756
|
+
if (valibotAction.requirement.flags) errors = addError(errors, "RegExp flags are not supported by JSON Schema.");
|
|
757
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
758
|
+
else jsonSchema.pattern = valibotAction.requirement.source;
|
|
759
|
+
break;
|
|
760
|
+
case "safe_integer":
|
|
761
|
+
jsonSchema.type = "integer";
|
|
762
|
+
if (typeof jsonSchema.minimum !== "number" || jsonSchema.minimum < Number.MIN_SAFE_INTEGER) jsonSchema.minimum = Number.MIN_SAFE_INTEGER;
|
|
763
|
+
if (typeof jsonSchema.maximum !== "number" || jsonSchema.maximum > Number.MAX_SAFE_INTEGER) jsonSchema.maximum = Number.MAX_SAFE_INTEGER;
|
|
764
|
+
break;
|
|
765
|
+
case "starts_with":
|
|
766
|
+
if (jsonSchema.pattern) errors = addError(errors, `The "${valibotAction.type}" action is not supported in combination with another regex action.`);
|
|
767
|
+
else jsonSchema.pattern = `^${escapeRegExp(valibotAction.requirement)}`;
|
|
768
|
+
break;
|
|
769
|
+
case "title":
|
|
770
|
+
jsonSchema.title = valibotAction.title;
|
|
771
|
+
break;
|
|
772
|
+
case "url":
|
|
773
|
+
jsonSchema.format = "uri";
|
|
774
|
+
break;
|
|
775
|
+
case "uuid":
|
|
776
|
+
jsonSchema.format = "uuid";
|
|
777
|
+
break;
|
|
778
|
+
case "value":
|
|
779
|
+
if (!isJsonConstValue(valibotAction.requirement)) {
|
|
780
|
+
errors = addError(errors, "The requirement of the \"value\" action is not JSON compatible.");
|
|
781
|
+
break;
|
|
782
|
+
}
|
|
783
|
+
if (config?.target === "openapi-3.0") jsonSchema.enum = [valibotAction.requirement];
|
|
784
|
+
else jsonSchema.const = valibotAction.requirement;
|
|
785
|
+
break;
|
|
786
|
+
case "values":
|
|
787
|
+
if (!isJsonEnumValues(valibotAction.requirement)) {
|
|
788
|
+
errors = addError(errors, "A requirement of the \"values\" action is not JSON compatible.");
|
|
789
|
+
break;
|
|
790
|
+
}
|
|
791
|
+
jsonSchema.enum = valibotAction.requirement;
|
|
792
|
+
break;
|
|
793
|
+
default: errors = addError(errors, `The "${valibotAction.type}" action cannot be converted to JSON Schema.`);
|
|
794
|
+
}
|
|
795
|
+
if (config?.overrideAction) {
|
|
796
|
+
const actionOverride = config.overrideAction({
|
|
797
|
+
valibotAction,
|
|
798
|
+
jsonSchema,
|
|
799
|
+
errors
|
|
800
|
+
});
|
|
801
|
+
if (actionOverride) return { ...actionOverride };
|
|
802
|
+
}
|
|
803
|
+
if (errors) for (const message of errors) handleError(message, config);
|
|
804
|
+
return jsonSchema;
|
|
805
|
+
}
|
|
806
|
+
/**
|
|
807
|
+
* Flattens a Valibot pipe by recursively expanding nested pipes.
|
|
808
|
+
*
|
|
809
|
+
* @param pipe The pipeline to flatten.
|
|
810
|
+
*
|
|
811
|
+
* @returns A flat pipeline.
|
|
812
|
+
*/
|
|
813
|
+
function flattenPipe(pipe) {
|
|
814
|
+
return pipe.flatMap((item) => "pipe" in item ? flattenPipe(item.pipe) : item);
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Returns the JSON Pointer reference for a definition key.
|
|
818
|
+
*
|
|
819
|
+
* @param referenceId The unescaped definition key.
|
|
820
|
+
*
|
|
821
|
+
* @returns The encoded JSON Pointer fragment.
|
|
822
|
+
*/
|
|
823
|
+
function getDefinitionRef(referenceId) {
|
|
824
|
+
return `#/$defs/${referenceId.replaceAll("~", "~0").replaceAll("/", "~1")}`;
|
|
825
|
+
}
|
|
826
|
+
let refCount = 0;
|
|
827
|
+
/**
|
|
828
|
+
* Converts any supported Valibot schema to the JSON Schema format.
|
|
829
|
+
*
|
|
830
|
+
* @param jsonSchema The JSON Schema object.
|
|
831
|
+
* @param valibotSchema The Valibot schema object.
|
|
832
|
+
* @param config The conversion configuration.
|
|
833
|
+
* @param context The conversion context.
|
|
834
|
+
* @param skipRef Whether to skip using a reference.
|
|
835
|
+
*
|
|
836
|
+
* @returns The converted JSON Schema.
|
|
837
|
+
*/
|
|
838
|
+
function convertSchema(jsonSchema, valibotSchema, config, context, skipRef = false) {
|
|
839
|
+
if (!skipRef) {
|
|
840
|
+
const referenceId = context.referenceMap.get(valibotSchema);
|
|
841
|
+
if (referenceId) {
|
|
842
|
+
jsonSchema.$ref = getDefinitionRef(referenceId);
|
|
843
|
+
if (config?.overrideRef) {
|
|
844
|
+
const refOverride = config.overrideRef({
|
|
845
|
+
...context,
|
|
846
|
+
referenceId,
|
|
847
|
+
valibotSchema,
|
|
848
|
+
jsonSchema
|
|
849
|
+
});
|
|
850
|
+
if (refOverride) jsonSchema.$ref = refOverride;
|
|
851
|
+
}
|
|
852
|
+
return jsonSchema;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
if ("pipe" in valibotSchema) {
|
|
856
|
+
const flatPipe = flattenPipe(valibotSchema.pipe);
|
|
857
|
+
let startIndex = 0;
|
|
858
|
+
let stopIndex = flatPipe.length - 1;
|
|
859
|
+
if (config?.typeMode === "input") {
|
|
860
|
+
const inputStopIndex = flatPipe.slice(1).findIndex((item) => item.kind === "schema" || item.kind === "transformation" && (item.type === "find_item" || item.type === "parse_json" || item.type === "raw_transform" || item.type === "reduce_items" || item.type === "stringify_json" || item.type === "to_bigint" || item.type === "to_boolean" || item.type === "to_date" || item.type === "to_number" || item.type === "to_string" || item.type === "transform"));
|
|
861
|
+
if (inputStopIndex !== -1) stopIndex = inputStopIndex;
|
|
862
|
+
} else if (config?.typeMode === "output") {
|
|
863
|
+
const outputStartIndex = flatPipe.findLastIndex((item) => item.kind === "schema");
|
|
864
|
+
if (outputStartIndex !== -1) startIndex = outputStartIndex;
|
|
865
|
+
}
|
|
866
|
+
for (let index = startIndex; index <= stopIndex; index++) {
|
|
867
|
+
const valibotPipeItem = flatPipe[index];
|
|
868
|
+
if (valibotPipeItem.kind === "schema") {
|
|
869
|
+
if (index > startIndex) handleError("Set the \"typeMode\" config to \"input\" or \"output\" to convert pipelines with multiple schemas.", config);
|
|
870
|
+
jsonSchema = convertSchema(jsonSchema, valibotPipeItem, config, context, true);
|
|
871
|
+
} else jsonSchema = convertAction(jsonSchema, valibotPipeItem, config);
|
|
872
|
+
}
|
|
873
|
+
return jsonSchema;
|
|
874
|
+
}
|
|
875
|
+
let errors;
|
|
876
|
+
switch (valibotSchema.type) {
|
|
877
|
+
case "boolean":
|
|
878
|
+
jsonSchema.type = "boolean";
|
|
879
|
+
break;
|
|
880
|
+
case "null":
|
|
881
|
+
if (config?.target === "openapi-3.0") jsonSchema.enum = [null];
|
|
882
|
+
else jsonSchema.type = "null";
|
|
883
|
+
break;
|
|
884
|
+
case "number":
|
|
885
|
+
jsonSchema.type = "number";
|
|
886
|
+
break;
|
|
887
|
+
case "string":
|
|
888
|
+
jsonSchema.type = "string";
|
|
889
|
+
break;
|
|
890
|
+
case "array":
|
|
891
|
+
jsonSchema.type = "array";
|
|
892
|
+
jsonSchema.items = convertSchema({}, valibotSchema.item, config, context);
|
|
893
|
+
break;
|
|
894
|
+
case "tuple":
|
|
895
|
+
case "tuple_with_rest":
|
|
896
|
+
case "loose_tuple":
|
|
897
|
+
case "strict_tuple":
|
|
898
|
+
jsonSchema.type = "array";
|
|
899
|
+
if (config?.target === "openapi-3.0") {
|
|
900
|
+
jsonSchema.items = { anyOf: [] };
|
|
901
|
+
jsonSchema.minItems = valibotSchema.items.length;
|
|
902
|
+
for (const item of valibotSchema.items) jsonSchema.items.anyOf.push(convertSchema({}, item, config, context));
|
|
903
|
+
if (valibotSchema.type === "tuple_with_rest") jsonSchema.items.anyOf.push(convertSchema({}, valibotSchema.rest, config, context));
|
|
904
|
+
else if (valibotSchema.type === "strict_tuple" || valibotSchema.type === "tuple") jsonSchema.maxItems = valibotSchema.items.length;
|
|
905
|
+
} else if (config?.target === "draft-2020-12") {
|
|
906
|
+
jsonSchema.prefixItems = [];
|
|
907
|
+
jsonSchema.minItems = valibotSchema.items.length;
|
|
908
|
+
for (const item of valibotSchema.items) jsonSchema.prefixItems.push(convertSchema({}, item, config, context));
|
|
909
|
+
if (valibotSchema.type === "tuple_with_rest") jsonSchema.items = convertSchema({}, valibotSchema.rest, config, context);
|
|
910
|
+
else if (valibotSchema.type === "strict_tuple") jsonSchema.items = false;
|
|
911
|
+
} else {
|
|
912
|
+
jsonSchema.items = [];
|
|
913
|
+
jsonSchema.minItems = valibotSchema.items.length;
|
|
914
|
+
for (const item of valibotSchema.items) jsonSchema.items.push(convertSchema({}, item, config, context));
|
|
915
|
+
if (valibotSchema.type === "tuple_with_rest") jsonSchema.additionalItems = convertSchema({}, valibotSchema.rest, config, context);
|
|
916
|
+
else if (valibotSchema.type === "strict_tuple") jsonSchema.additionalItems = false;
|
|
917
|
+
}
|
|
918
|
+
break;
|
|
919
|
+
case "object":
|
|
920
|
+
case "object_with_rest":
|
|
921
|
+
case "loose_object":
|
|
922
|
+
case "strict_object":
|
|
923
|
+
jsonSchema.type = "object";
|
|
924
|
+
jsonSchema.properties = {};
|
|
925
|
+
jsonSchema.required = [];
|
|
926
|
+
for (const key in valibotSchema.entries) {
|
|
927
|
+
const entry = valibotSchema.entries[key];
|
|
928
|
+
jsonSchema.properties[key] = convertSchema({}, entry, config, context);
|
|
929
|
+
if (entry.type !== "exact_optional" && entry.type !== "nullish" && entry.type !== "optional") jsonSchema.required.push(key);
|
|
930
|
+
}
|
|
931
|
+
if (valibotSchema.type === "object_with_rest") jsonSchema.additionalProperties = convertSchema({}, valibotSchema.rest, config, context);
|
|
932
|
+
else if (valibotSchema.type === "strict_object") jsonSchema.additionalProperties = false;
|
|
933
|
+
break;
|
|
934
|
+
case "record":
|
|
935
|
+
if (config?.target === "openapi-3.0" && "pipe" in valibotSchema.key) errors = addError(errors, "The \"record\" schema with a schema for the key that contains a \"pipe\" cannot be converted to JSON Schema.");
|
|
936
|
+
if (valibotSchema.key.type !== "string") errors = addError(errors, `The "record" schema with the "${valibotSchema.key.type}" schema for the key cannot be converted to JSON Schema.`);
|
|
937
|
+
jsonSchema.type = "object";
|
|
938
|
+
if (config?.target !== "openapi-3.0") jsonSchema.propertyNames = convertSchema({}, valibotSchema.key, config, context);
|
|
939
|
+
jsonSchema.additionalProperties = convertSchema({}, valibotSchema.value, config, context);
|
|
940
|
+
break;
|
|
941
|
+
case "any":
|
|
942
|
+
case "unknown": break;
|
|
943
|
+
case "never":
|
|
944
|
+
jsonSchema.not = {};
|
|
945
|
+
break;
|
|
946
|
+
case "nullable":
|
|
947
|
+
case "nullish":
|
|
948
|
+
if (config?.target === "openapi-3.0") {
|
|
949
|
+
const innerSchema = convertSchema({}, valibotSchema.wrapped, config, context);
|
|
950
|
+
Object.assign(jsonSchema, innerSchema);
|
|
951
|
+
jsonSchema.nullable = true;
|
|
952
|
+
} else jsonSchema.anyOf = [convertSchema({}, valibotSchema.wrapped, config, context), { type: "null" }];
|
|
953
|
+
if (valibotSchema.default !== void 0) jsonSchema.default = typeof valibotSchema.default === "function" ? valibotSchema.default() : valibotSchema.default;
|
|
954
|
+
break;
|
|
955
|
+
case "exact_optional":
|
|
956
|
+
case "optional":
|
|
957
|
+
case "undefinedable":
|
|
958
|
+
jsonSchema = convertSchema(jsonSchema, valibotSchema.wrapped, config, context);
|
|
959
|
+
if (valibotSchema.default !== void 0) jsonSchema.default = typeof valibotSchema.default === "function" ? valibotSchema.default() : valibotSchema.default;
|
|
960
|
+
break;
|
|
961
|
+
case "literal":
|
|
962
|
+
if (typeof valibotSchema.literal !== "boolean" && typeof valibotSchema.literal !== "number" && typeof valibotSchema.literal !== "string") errors = addError(errors, "The value of the \"literal\" schema is not JSON compatible.");
|
|
963
|
+
if (config?.target === "openapi-3.0") jsonSchema.enum = [valibotSchema.literal];
|
|
964
|
+
else jsonSchema.const = valibotSchema.literal;
|
|
965
|
+
break;
|
|
966
|
+
case "enum":
|
|
967
|
+
jsonSchema.enum = valibotSchema.options;
|
|
968
|
+
if (valibotSchema.options.every((option) => typeof option === "string")) jsonSchema.type = "string";
|
|
969
|
+
else if (valibotSchema.options.every((option) => typeof option === "number")) jsonSchema.type = "number";
|
|
970
|
+
else if (config?.target !== "openapi-3.0") jsonSchema.type = ["string", "number"];
|
|
971
|
+
break;
|
|
972
|
+
case "picklist": {
|
|
973
|
+
const hasInvalidOption = valibotSchema.options.some((option) => typeof option !== "number" && typeof option !== "string");
|
|
974
|
+
if (hasInvalidOption) errors = addError(errors, "An option of the \"picklist\" schema is not JSON compatible.");
|
|
975
|
+
jsonSchema.enum = valibotSchema.options;
|
|
976
|
+
if (valibotSchema.options.every((option) => typeof option === "string")) jsonSchema.type = "string";
|
|
977
|
+
else if (valibotSchema.options.every((option) => typeof option === "number")) jsonSchema.type = "number";
|
|
978
|
+
else if (!hasInvalidOption && config?.target !== "openapi-3.0") jsonSchema.type = ["string", "number"];
|
|
979
|
+
break;
|
|
980
|
+
}
|
|
981
|
+
case "union":
|
|
982
|
+
jsonSchema.anyOf = valibotSchema.options.map((option) => convertSchema({}, option, config, context));
|
|
983
|
+
break;
|
|
984
|
+
case "variant":
|
|
985
|
+
jsonSchema.oneOf = valibotSchema.options.map((option) => convertSchema({}, option, config, context));
|
|
986
|
+
break;
|
|
987
|
+
case "intersect":
|
|
988
|
+
jsonSchema.allOf = valibotSchema.options.map((option) => convertSchema({}, option, config, context));
|
|
989
|
+
break;
|
|
990
|
+
case "lazy": {
|
|
991
|
+
let wrappedValibotSchema = context.getterMap.get(valibotSchema.getter);
|
|
992
|
+
if (!wrappedValibotSchema) {
|
|
993
|
+
wrappedValibotSchema = valibotSchema.getter(void 0);
|
|
994
|
+
context.getterMap.set(valibotSchema.getter, wrappedValibotSchema);
|
|
995
|
+
}
|
|
996
|
+
let referenceId = context.referenceMap.get(wrappedValibotSchema);
|
|
997
|
+
if (!referenceId) {
|
|
998
|
+
referenceId = `${refCount++}`;
|
|
999
|
+
context.referenceMap.set(wrappedValibotSchema, referenceId);
|
|
1000
|
+
context.definitions[referenceId] = convertSchema({}, wrappedValibotSchema, config, context, true);
|
|
1001
|
+
}
|
|
1002
|
+
jsonSchema.$ref = getDefinitionRef(referenceId);
|
|
1003
|
+
if (config?.overrideRef) {
|
|
1004
|
+
const refOverride = config.overrideRef({
|
|
1005
|
+
...context,
|
|
1006
|
+
referenceId,
|
|
1007
|
+
valibotSchema: wrappedValibotSchema,
|
|
1008
|
+
jsonSchema
|
|
1009
|
+
});
|
|
1010
|
+
if (refOverride) jsonSchema.$ref = refOverride;
|
|
1011
|
+
}
|
|
1012
|
+
break;
|
|
1013
|
+
}
|
|
1014
|
+
default: errors = addError(errors, `The "${valibotSchema.type}" schema cannot be converted to JSON Schema.`);
|
|
1015
|
+
}
|
|
1016
|
+
if (config?.overrideSchema) {
|
|
1017
|
+
const schemaOverride = config.overrideSchema({
|
|
1018
|
+
...context,
|
|
1019
|
+
referenceId: context.referenceMap.get(valibotSchema),
|
|
1020
|
+
valibotSchema,
|
|
1021
|
+
jsonSchema,
|
|
1022
|
+
errors
|
|
1023
|
+
});
|
|
1024
|
+
if (schemaOverride) return { ...schemaOverride };
|
|
1025
|
+
}
|
|
1026
|
+
if (errors) for (const message of errors) handleError(message, config);
|
|
1027
|
+
return jsonSchema;
|
|
1028
|
+
}
|
|
1029
|
+
let store;
|
|
1030
|
+
/**
|
|
1031
|
+
* Adds new definitions to the global schema definitions.
|
|
1032
|
+
*
|
|
1033
|
+
* @param definitions The schema definitions.
|
|
1034
|
+
*
|
|
1035
|
+
* @beta
|
|
1036
|
+
*/
|
|
1037
|
+
function addGlobalDefs(definitions) {
|
|
1038
|
+
store = {
|
|
1039
|
+
...store ?? {},
|
|
1040
|
+
...definitions
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
/**
|
|
1044
|
+
* Returns the current global schema definitions.
|
|
1045
|
+
*
|
|
1046
|
+
* @returns The schema definitions.
|
|
1047
|
+
*
|
|
1048
|
+
* @beta
|
|
1049
|
+
*/
|
|
1050
|
+
function getGlobalDefs() {
|
|
1051
|
+
return store;
|
|
1052
|
+
}
|
|
1053
|
+
/**
|
|
1054
|
+
* Converts a Valibot schema to the JSON Schema format.
|
|
1055
|
+
*
|
|
1056
|
+
* @param schema The Valibot schema object.
|
|
1057
|
+
* @param config The JSON Schema configuration.
|
|
1058
|
+
*
|
|
1059
|
+
* @returns The converted JSON Schema.
|
|
1060
|
+
*/
|
|
1061
|
+
function toJsonSchema(schema, config) {
|
|
1062
|
+
const context = {
|
|
1063
|
+
definitions: {},
|
|
1064
|
+
referenceMap: /* @__PURE__ */ new Map(),
|
|
1065
|
+
getterMap: /* @__PURE__ */ new Map()
|
|
1066
|
+
};
|
|
1067
|
+
const definitions = config?.definitions ?? getGlobalDefs();
|
|
1068
|
+
if (definitions) {
|
|
1069
|
+
for (const key in definitions) context.referenceMap.set(definitions[key], key);
|
|
1070
|
+
for (const key in definitions) context.definitions[key] = convertSchema({}, definitions[key], config, context, true);
|
|
1071
|
+
}
|
|
1072
|
+
const jsonSchema = convertSchema({}, schema, config, context);
|
|
1073
|
+
const target = config?.target ?? "draft-07";
|
|
1074
|
+
if (target === "draft-2020-12") jsonSchema.$schema = "https://json-schema.org/draft/2020-12/schema";
|
|
1075
|
+
else if (target === "draft-07") jsonSchema.$schema = "http://json-schema.org/draft-07/schema#";
|
|
1076
|
+
if (context.referenceMap.size) jsonSchema.$defs = context.definitions;
|
|
1077
|
+
return jsonSchema;
|
|
1078
|
+
}
|
|
1079
|
+
/**
|
|
1080
|
+
* Converts Valibot schema definitions to JSON Schema definitions.
|
|
1081
|
+
*
|
|
1082
|
+
* @param definitions The Valibot schema definitions.
|
|
1083
|
+
* @param config The JSON Schema configuration.
|
|
1084
|
+
*
|
|
1085
|
+
* @returns The converted JSON Schema definitions.
|
|
1086
|
+
*/
|
|
1087
|
+
function toJsonSchemaDefs(definitions, config) {
|
|
1088
|
+
const context = {
|
|
1089
|
+
definitions: {},
|
|
1090
|
+
referenceMap: /* @__PURE__ */ new Map(),
|
|
1091
|
+
getterMap: /* @__PURE__ */ new Map()
|
|
1092
|
+
};
|
|
1093
|
+
for (const key in definitions) context.referenceMap.set(definitions[key], key);
|
|
1094
|
+
for (const key in definitions) context.definitions[key] = convertSchema({}, definitions[key], config, context, true);
|
|
1095
|
+
return context.definitions;
|
|
1096
|
+
}
|
|
1097
|
+
const SUPPORTED_TARGETS = [
|
|
1098
|
+
"draft-07",
|
|
1099
|
+
"draft-2020-12",
|
|
1100
|
+
"openapi-3.0"
|
|
1101
|
+
];
|
|
1102
|
+
/**
|
|
1103
|
+
* Converts a Valibot schema to the Standard JSON Schema format.
|
|
1104
|
+
*
|
|
1105
|
+
* @param schema The Valibot schema object.
|
|
1106
|
+
*
|
|
1107
|
+
* @returns The Standard JSON Schema.
|
|
1108
|
+
*/
|
|
1109
|
+
function toStandardJsonSchema(schema) {
|
|
1110
|
+
return { "~standard": {
|
|
1111
|
+
...schema["~standard"],
|
|
1112
|
+
jsonSchema: {
|
|
1113
|
+
input(options) {
|
|
1114
|
+
if (SUPPORTED_TARGETS.includes(options.target)) return toJsonSchema(schema, {
|
|
1115
|
+
typeMode: "input",
|
|
1116
|
+
target: options.target,
|
|
1117
|
+
...options.libraryOptions
|
|
1118
|
+
});
|
|
1119
|
+
throw new Error(`Unsupported target: ${options.target}`);
|
|
1120
|
+
},
|
|
1121
|
+
output(options) {
|
|
1122
|
+
if (SUPPORTED_TARGETS.includes(options.target)) return toJsonSchema(schema, {
|
|
1123
|
+
typeMode: "output",
|
|
1124
|
+
target: options.target,
|
|
1125
|
+
...options.libraryOptions
|
|
1126
|
+
});
|
|
1127
|
+
throw new Error(`Unsupported target: ${options.target}`);
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
} };
|
|
1131
|
+
}
|
|
1132
|
+
//#endregion
|
|
1133
|
+
//#region ../../node_modules/.pnpm/@xsai+shared@0.5.0-beta.7/node_modules/@xsai/shared/dist/index.js
|
|
1134
|
+
var XSAIError = class extends Error {
|
|
1135
|
+
constructor(message, code, options = {}) {
|
|
1136
|
+
super(message, { cause: options.cause });
|
|
1137
|
+
this.code = code;
|
|
1138
|
+
this.name = new.target.name;
|
|
1139
|
+
}
|
|
1140
|
+
static isInstance(error) {
|
|
1141
|
+
return error instanceof this;
|
|
1142
|
+
}
|
|
1143
|
+
};
|
|
1144
|
+
var APICallError = class extends XSAIError {
|
|
1145
|
+
constructor(message, options) {
|
|
1146
|
+
super(message, "api_call_error", options);
|
|
1147
|
+
this.requestBody = options.requestBody;
|
|
1148
|
+
this.response = options.response;
|
|
1149
|
+
this.responseBody = options.responseBody;
|
|
1150
|
+
this.responseHeaders = Object.fromEntries(options.response.headers.entries());
|
|
1151
|
+
this.statusCode = options.response.status;
|
|
1152
|
+
this.statusText = options.response.statusText;
|
|
1153
|
+
this.url = options.response.url;
|
|
1154
|
+
}
|
|
1155
|
+
};
|
|
1156
|
+
var InvalidResponseError = class extends XSAIError {
|
|
1157
|
+
constructor(message, options) {
|
|
1158
|
+
super(message, "invalid_response", options);
|
|
1159
|
+
Object.assign(this, options);
|
|
1160
|
+
}
|
|
1161
|
+
};
|
|
1162
|
+
var InvalidToolCallError = class extends XSAIError {
|
|
1163
|
+
constructor(message, options) {
|
|
1164
|
+
super(message, "invalid_tool_call", options);
|
|
1165
|
+
Object.assign(this, options);
|
|
1166
|
+
}
|
|
1167
|
+
};
|
|
1168
|
+
var InvalidToolInputError = class extends XSAIError {
|
|
1169
|
+
constructor(message, options) {
|
|
1170
|
+
super(message, "invalid_tool_input", options);
|
|
1171
|
+
Object.assign(this, options);
|
|
1172
|
+
}
|
|
1173
|
+
};
|
|
1174
|
+
var JSONParseError = class extends XSAIError {
|
|
1175
|
+
constructor(message, options) {
|
|
1176
|
+
super(message, "json_parse_error", options);
|
|
1177
|
+
this.text = options.text;
|
|
1178
|
+
}
|
|
1179
|
+
};
|
|
1180
|
+
var ToolExecutionError = class extends XSAIError {
|
|
1181
|
+
constructor(message, options) {
|
|
1182
|
+
super(message, "tool_execution_error", options);
|
|
1183
|
+
Object.assign(this, options);
|
|
1184
|
+
}
|
|
1185
|
+
};
|
|
1186
|
+
const strCamelToSnake = (str) => str.replace(/[A-Z]/g, (s) => `_${s.toLowerCase()}`);
|
|
1187
|
+
const objCamelToSnake = (obj) => Object.fromEntries(Object.entries(obj).map(([k, v]) => [strCamelToSnake(k), v]));
|
|
1188
|
+
const clean = (obj) => Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== void 0));
|
|
1189
|
+
const requestBody = (body) => JSON.stringify(objCamelToSnake(clean({
|
|
1190
|
+
...body,
|
|
1191
|
+
abortSignal: void 0,
|
|
1192
|
+
apiKey: void 0,
|
|
1193
|
+
baseURL: void 0,
|
|
1194
|
+
fetch: void 0,
|
|
1195
|
+
headers: void 0
|
|
1196
|
+
})));
|
|
1197
|
+
const requestHeaders = (headers, apiKey) => clean({
|
|
1198
|
+
Authorization: apiKey !== void 0 ? `Bearer ${apiKey}` : void 0,
|
|
1199
|
+
...headers
|
|
1200
|
+
});
|
|
1201
|
+
const requestURL = (path, baseURL) => {
|
|
1202
|
+
const base = baseURL.toString();
|
|
1203
|
+
return new URL(path, base.endsWith("/") ? base : `${base}/`);
|
|
1204
|
+
};
|
|
1205
|
+
const responseCatch = async (res) => {
|
|
1206
|
+
if (!res.ok) {
|
|
1207
|
+
const responseBody = await res.text();
|
|
1208
|
+
throw new APICallError(`Remote sent ${res.status} response: ${responseBody}`, {
|
|
1209
|
+
response: res,
|
|
1210
|
+
responseBody
|
|
1211
|
+
});
|
|
1212
|
+
}
|
|
1213
|
+
if (!res.body) throw new InvalidResponseError("Response body is empty from remote server", {
|
|
1214
|
+
reason: "empty_body",
|
|
1215
|
+
response: res
|
|
1216
|
+
});
|
|
1217
|
+
if (!(res.body instanceof ReadableStream)) {
|
|
1218
|
+
const contentType = res.headers.get("Content-Type");
|
|
1219
|
+
throw new InvalidResponseError(`Expected Response body to be a ReadableStream, but got ${String(res.body)}; Content Type is ${contentType}`, {
|
|
1220
|
+
body: res.body,
|
|
1221
|
+
contentType,
|
|
1222
|
+
reason: "invalid_body",
|
|
1223
|
+
response: res
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1226
|
+
return res;
|
|
1227
|
+
};
|
|
1228
|
+
const postJSON = async (path, options) => (options.fetch ?? globalThis.fetch)(requestURL(path, options.baseURL), {
|
|
1229
|
+
body: requestBody(options),
|
|
1230
|
+
headers: requestHeaders({
|
|
1231
|
+
"Content-Type": "application/json",
|
|
1232
|
+
...options.headers
|
|
1233
|
+
}, options.apiKey),
|
|
1234
|
+
method: "POST",
|
|
1235
|
+
signal: options.abortSignal
|
|
1236
|
+
}).then(responseCatch);
|
|
1237
|
+
const responseJSON = async (res) => {
|
|
1238
|
+
const text = await res.text();
|
|
1239
|
+
try {
|
|
1240
|
+
return JSON.parse(text);
|
|
1241
|
+
} catch (cause) {
|
|
1242
|
+
throw new JSONParseError(`Failed to parse response, response body: ${text}`, {
|
|
1243
|
+
cause,
|
|
1244
|
+
text
|
|
1245
|
+
});
|
|
1246
|
+
}
|
|
1247
|
+
};
|
|
1248
|
+
const trampoline = async (fn) => {
|
|
1249
|
+
let result = await fn();
|
|
1250
|
+
while (result instanceof Function) result = await result();
|
|
1251
|
+
return result;
|
|
1252
|
+
};
|
|
1253
|
+
//#endregion
|
|
1254
|
+
//#region ../../node_modules/.pnpm/@xsai+shared-chat@0.5.0-beta.7/node_modules/@xsai/shared-chat/dist/index.js
|
|
1255
|
+
const chat = async (options) => postJSON("chat/completions", {
|
|
1256
|
+
...options,
|
|
1257
|
+
maxSteps: void 0,
|
|
1258
|
+
onEvent: void 0,
|
|
1259
|
+
onFinish: void 0,
|
|
1260
|
+
onStepFinish: void 0,
|
|
1261
|
+
postToolCall: void 0,
|
|
1262
|
+
prepareStep: void 0,
|
|
1263
|
+
preToolCall: void 0,
|
|
1264
|
+
stopWhen: void 0,
|
|
1265
|
+
tools: options.tools?.map(({ execute: _execute, ...tool }) => tool)
|
|
1266
|
+
});
|
|
1267
|
+
const toToolMessageContent = (result) => {
|
|
1268
|
+
if (typeof result === "string") return result;
|
|
1269
|
+
if (Array.isArray(result)) {
|
|
1270
|
+
if (result.every((item) => item !== null && typeof item === "object" && "type" in item && [
|
|
1271
|
+
"file",
|
|
1272
|
+
"image_url",
|
|
1273
|
+
"input_audio",
|
|
1274
|
+
"text"
|
|
1275
|
+
].includes(item.type))) return result;
|
|
1276
|
+
}
|
|
1277
|
+
return JSON.stringify(result);
|
|
1278
|
+
};
|
|
1279
|
+
const isAbortError = (error, abortSignal) => abortSignal?.aborted === true && error === abortSignal.reason || error instanceof Error && error.name === "AbortError";
|
|
1280
|
+
const parseToolInput = async (tool, input) => {
|
|
1281
|
+
let result;
|
|
1282
|
+
try {
|
|
1283
|
+
result = JSON.parse(input.trim() || "{}");
|
|
1284
|
+
} catch (cause) {
|
|
1285
|
+
throw new InvalidToolInputError(`Failed to parse tool input for "${tool.function.name}".`, {
|
|
1286
|
+
cause,
|
|
1287
|
+
toolInput: input,
|
|
1288
|
+
toolName: tool.function.name
|
|
1289
|
+
});
|
|
1290
|
+
}
|
|
1291
|
+
if (tool.validate) {
|
|
1292
|
+
const validated = await tool.validate(result);
|
|
1293
|
+
if (validated.issues) throw new InvalidToolInputError(`Tool input validation failed for "${tool.function.name}".`, {
|
|
1294
|
+
cause: validated.issues,
|
|
1295
|
+
toolInput: result,
|
|
1296
|
+
toolName: tool.function.name
|
|
1297
|
+
});
|
|
1298
|
+
result = validated.value;
|
|
1299
|
+
}
|
|
1300
|
+
return result;
|
|
1301
|
+
};
|
|
1302
|
+
const runTool = async (tool, options) => {
|
|
1303
|
+
try {
|
|
1304
|
+
return await tool.execute(options.args, options.toolExecuteOptions);
|
|
1305
|
+
} catch (cause) {
|
|
1306
|
+
if (isAbortError(cause, options.toolExecuteOptions.abortSignal)) throw cause;
|
|
1307
|
+
throw new ToolExecutionError(`Tool "${tool.function.name}" execution failed.`, {
|
|
1308
|
+
cause,
|
|
1309
|
+
toolCallId: options.toolExecuteOptions.toolCallId,
|
|
1310
|
+
toolInput: options.args,
|
|
1311
|
+
toolName: tool.function.name
|
|
1312
|
+
});
|
|
1313
|
+
}
|
|
1314
|
+
};
|
|
1315
|
+
const assertSameToolCallId = (source, next, label) => {
|
|
1316
|
+
if (source === next.toolCallId) return;
|
|
1317
|
+
throw new InvalidToolCallError(`${label} must preserve toolCallId "${source}".`, {
|
|
1318
|
+
reason: "tool_call_id_mismatch",
|
|
1319
|
+
toolCall: next
|
|
1320
|
+
});
|
|
1321
|
+
};
|
|
1322
|
+
const findTool = (tools, toolName, toolCall) => {
|
|
1323
|
+
const tool = tools?.find((tool2) => tool2.function.name === toolName);
|
|
1324
|
+
if (!tool) {
|
|
1325
|
+
const availableTools = tools?.map((tool2) => tool2.function.name);
|
|
1326
|
+
throw new InvalidToolCallError(`Model tried to call unavailable tool "${toolName}", ${availableTools == null || availableTools.length === 0 ? "No tools are available" : `Available tools: ${availableTools.join(", ")}`}.`, {
|
|
1327
|
+
availableTools,
|
|
1328
|
+
reason: "unknown_tool",
|
|
1329
|
+
toolCall,
|
|
1330
|
+
toolName
|
|
1331
|
+
});
|
|
1332
|
+
}
|
|
1333
|
+
return tool;
|
|
1334
|
+
};
|
|
1335
|
+
const executeTool = async ({ abortSignal, messages, postToolCall, preToolCall, toolCall, tools, wrapResult }) => {
|
|
1336
|
+
const wrap = wrapResult ?? toToolMessageContent;
|
|
1337
|
+
const toolName = toolCall.function.name;
|
|
1338
|
+
const toolArguments = toolCall.function.arguments;
|
|
1339
|
+
if (toolName == null) throw new InvalidToolCallError(`Missing toolCall.function.name: ${JSON.stringify(toolCall)}`, {
|
|
1340
|
+
reason: "missing_name",
|
|
1341
|
+
toolCall
|
|
1342
|
+
});
|
|
1343
|
+
if (toolArguments == null) throw new InvalidToolCallError(`Missing toolCall.function.arguments: ${JSON.stringify(toolCall)}`, {
|
|
1344
|
+
reason: "missing_arguments",
|
|
1345
|
+
toolCall
|
|
1346
|
+
});
|
|
1347
|
+
const toolExecuteOptions = {
|
|
1348
|
+
abortSignal,
|
|
1349
|
+
messages,
|
|
1350
|
+
toolCallId: toolCall.id
|
|
1351
|
+
};
|
|
1352
|
+
let completionToolCall = {
|
|
1353
|
+
args: toolArguments,
|
|
1354
|
+
toolCallId: toolCall.id,
|
|
1355
|
+
toolCallType: "function",
|
|
1356
|
+
toolName
|
|
1357
|
+
};
|
|
1358
|
+
let completionToolResult;
|
|
1359
|
+
const preToolCallResult = await preToolCall?.(completionToolCall, toolExecuteOptions);
|
|
1360
|
+
if (preToolCallResult) {
|
|
1361
|
+
assertSameToolCallId(completionToolCall.toolCallId, preToolCallResult, "preToolCallResult");
|
|
1362
|
+
if ("result" in preToolCallResult) completionToolResult = preToolCallResult;
|
|
1363
|
+
else completionToolCall = preToolCallResult;
|
|
1364
|
+
}
|
|
1365
|
+
if (completionToolResult == null) {
|
|
1366
|
+
const tool = findTool(tools, completionToolCall.toolName, completionToolCall);
|
|
1367
|
+
const args = await parseToolInput(tool, completionToolCall.args);
|
|
1368
|
+
completionToolResult = {
|
|
1369
|
+
args,
|
|
1370
|
+
result: await runTool(tool, {
|
|
1371
|
+
args,
|
|
1372
|
+
toolExecuteOptions
|
|
1373
|
+
}),
|
|
1374
|
+
toolCallId: completionToolCall.toolCallId,
|
|
1375
|
+
toolName: completionToolCall.toolName
|
|
1376
|
+
};
|
|
1377
|
+
}
|
|
1378
|
+
const postToolCallResult = await postToolCall?.(completionToolResult, toolExecuteOptions);
|
|
1379
|
+
if (postToolCallResult) {
|
|
1380
|
+
assertSameToolCallId(completionToolResult.toolCallId, postToolCallResult, "postToolCallResult");
|
|
1381
|
+
completionToolResult = postToolCallResult;
|
|
1382
|
+
}
|
|
1383
|
+
return {
|
|
1384
|
+
completionToolCall,
|
|
1385
|
+
completionToolResult,
|
|
1386
|
+
result: wrap(completionToolResult.result)
|
|
1387
|
+
};
|
|
1388
|
+
};
|
|
1389
|
+
const resolvePrepareStep = async ({ input, model, prepareStep, stepNumber, steps, toolChoice }) => {
|
|
1390
|
+
const prepared = prepareStep == null ? void 0 : await prepareStep({
|
|
1391
|
+
input: structuredClone(input),
|
|
1392
|
+
model,
|
|
1393
|
+
stepNumber,
|
|
1394
|
+
steps: structuredClone(steps)
|
|
1395
|
+
});
|
|
1396
|
+
return {
|
|
1397
|
+
input: prepared?.input != null ? structuredClone(prepared.input) : input,
|
|
1398
|
+
model: prepared?.model ?? model,
|
|
1399
|
+
toolChoice: prepared?.toolChoice ?? toolChoice
|
|
1400
|
+
};
|
|
1401
|
+
};
|
|
1402
|
+
const stepCountAtLeast = (count) => ({ steps }) => steps.length >= count;
|
|
1403
|
+
const shouldStop = (stopWhen, context) => stopWhen(context);
|
|
1404
|
+
const computeTotalUsage = (totalUsage, usage) => totalUsage == null ? usage : {
|
|
1405
|
+
inputTokens: totalUsage.inputTokens + usage.inputTokens,
|
|
1406
|
+
outputTokens: totalUsage.outputTokens + usage.outputTokens,
|
|
1407
|
+
totalTokens: totalUsage.totalTokens + usage.totalTokens
|
|
1408
|
+
};
|
|
1409
|
+
const normalizeChatCompletionUsage = (usage) => ({
|
|
1410
|
+
inputTokens: usage.prompt_tokens,
|
|
1411
|
+
outputTokens: usage.completion_tokens,
|
|
1412
|
+
totalTokens: usage.total_tokens
|
|
1413
|
+
});
|
|
1414
|
+
//#endregion
|
|
1415
|
+
//#region ../../node_modules/.pnpm/@xsai+generate-text@0.5.0-beta.7/node_modules/@xsai/generate-text/dist/index.js
|
|
1416
|
+
const rawGenerateText = async (options) => {
|
|
1417
|
+
const messages = options.steps == null ? structuredClone(options.messages) : options.messages;
|
|
1418
|
+
const steps = options.steps ?? [];
|
|
1419
|
+
const stepOptions = await resolvePrepareStep({
|
|
1420
|
+
input: messages,
|
|
1421
|
+
model: options.model,
|
|
1422
|
+
prepareStep: options.prepareStep,
|
|
1423
|
+
stepNumber: steps.length,
|
|
1424
|
+
steps,
|
|
1425
|
+
toolChoice: options.toolChoice
|
|
1426
|
+
});
|
|
1427
|
+
return chat({
|
|
1428
|
+
...options,
|
|
1429
|
+
messages: stepOptions.input,
|
|
1430
|
+
model: stepOptions.model,
|
|
1431
|
+
steps: void 0,
|
|
1432
|
+
stream: false,
|
|
1433
|
+
toolChoice: stepOptions.toolChoice,
|
|
1434
|
+
totalUsage: void 0
|
|
1435
|
+
}).then(responseJSON).then(async (res) => {
|
|
1436
|
+
const { choices } = res;
|
|
1437
|
+
const usage = normalizeChatCompletionUsage(res.usage);
|
|
1438
|
+
const totalUsage = computeTotalUsage(options.totalUsage, usage);
|
|
1439
|
+
if (!choices?.length) {
|
|
1440
|
+
const responseBody = JSON.stringify(res);
|
|
1441
|
+
throw new InvalidResponseError(`No choices returned, response body: ${responseBody}`, {
|
|
1442
|
+
reason: "no_choices",
|
|
1443
|
+
responseBody
|
|
1444
|
+
});
|
|
1445
|
+
}
|
|
1446
|
+
const toolCalls = [];
|
|
1447
|
+
const toolResults = [];
|
|
1448
|
+
const { finish_reason: finishReason, message } = choices[0];
|
|
1449
|
+
const msgToolCalls = message?.tool_calls ?? [];
|
|
1450
|
+
const stopWhen = options.stopWhen ?? stepCountAtLeast(1);
|
|
1451
|
+
messages.push(message);
|
|
1452
|
+
if (msgToolCalls.length > 0) {
|
|
1453
|
+
const results = await Promise.all(msgToolCalls.map(async (toolCall) => executeTool({
|
|
1454
|
+
abortSignal: options.abortSignal,
|
|
1455
|
+
messages,
|
|
1456
|
+
postToolCall: options.postToolCall,
|
|
1457
|
+
preToolCall: options.preToolCall,
|
|
1458
|
+
toolCall,
|
|
1459
|
+
tools: options.tools
|
|
1460
|
+
})));
|
|
1461
|
+
for (const { completionToolCall, completionToolResult, result } of results) {
|
|
1462
|
+
toolCalls.push(completionToolCall);
|
|
1463
|
+
toolResults.push(completionToolResult);
|
|
1464
|
+
messages.push({
|
|
1465
|
+
content: result,
|
|
1466
|
+
role: "tool",
|
|
1467
|
+
tool_call_id: completionToolCall.toolCallId
|
|
1468
|
+
});
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
const step = {
|
|
1472
|
+
finishReason,
|
|
1473
|
+
text: Array.isArray(message.content) ? message.content.filter((m) => m.type === "text").map((m) => m.text).join("\n") : message.content,
|
|
1474
|
+
toolCalls,
|
|
1475
|
+
toolResults,
|
|
1476
|
+
usage
|
|
1477
|
+
};
|
|
1478
|
+
const stop = shouldStop(stopWhen, {
|
|
1479
|
+
input: messages,
|
|
1480
|
+
step,
|
|
1481
|
+
steps: [...steps, step]
|
|
1482
|
+
});
|
|
1483
|
+
const willContinue = toolCalls.length > 0 && !stop;
|
|
1484
|
+
steps.push(step);
|
|
1485
|
+
if (options.onStepFinish) await options.onStepFinish(step);
|
|
1486
|
+
if (!willContinue) return {
|
|
1487
|
+
finishReason: step.finishReason,
|
|
1488
|
+
messages,
|
|
1489
|
+
reasoningText: message.reasoning ?? message.reasoning_content,
|
|
1490
|
+
steps,
|
|
1491
|
+
text: step.text,
|
|
1492
|
+
toolCalls: step.toolCalls,
|
|
1493
|
+
toolResults: step.toolResults,
|
|
1494
|
+
totalUsage,
|
|
1495
|
+
usage: step.usage
|
|
1496
|
+
};
|
|
1497
|
+
else return async () => rawGenerateText({
|
|
1498
|
+
...options,
|
|
1499
|
+
messages,
|
|
1500
|
+
steps,
|
|
1501
|
+
totalUsage
|
|
1502
|
+
});
|
|
1503
|
+
});
|
|
1504
|
+
};
|
|
1505
|
+
const generateText = async (options) => trampoline(async () => rawGenerateText(options));
|
|
1506
|
+
//#endregion
|
|
1507
|
+
//#region ../../node_modules/.pnpm/@xsai+tool@0.5.0-beta.7_@valibot+to-json-schema@1.7.1_valibot@1.4.2_typescript@6.0.3____927f6822d23b3a98d537f6f3dbeccc01/node_modules/@xsai/tool/dist/index.js
|
|
1508
|
+
const rawTool = ({ description, execute, name, parameters, strict }) => ({
|
|
1509
|
+
execute,
|
|
1510
|
+
function: {
|
|
1511
|
+
description,
|
|
1512
|
+
name,
|
|
1513
|
+
parameters: strict !== false ? strictJsonSchema(parameters) : parameters,
|
|
1514
|
+
strict: strict ?? true
|
|
1515
|
+
},
|
|
1516
|
+
type: "function"
|
|
1517
|
+
});
|
|
1518
|
+
//#endregion
|
|
1519
|
+
//#region ../core/dist/structured-output.mjs
|
|
1520
|
+
const defaultMaxAttempts = 3;
|
|
1521
|
+
const defaultToolName = "reportFindings";
|
|
1522
|
+
var InvalidStructuredOutputError = class extends Error {
|
|
1523
|
+
constructor(message) {
|
|
1524
|
+
super(message);
|
|
1525
|
+
this.name = "InvalidStructuredOutputError";
|
|
1526
|
+
}
|
|
1527
|
+
};
|
|
1528
|
+
/** Standard instruction line for localized judge findings; undefined when no language is configured. */
|
|
1529
|
+
function formatOutputLanguageInstruction(outputLanguage) {
|
|
1530
|
+
return outputLanguage ? `Write all human-readable finding messages and suggestions in this language: ${outputLanguage}.` : void 0;
|
|
1531
|
+
}
|
|
1532
|
+
/** Prefixes each line with its 1-based number so schemas can ask for "left-column line numbers". */
|
|
1533
|
+
function formatSourceWithLineNumbers(source) {
|
|
1534
|
+
return source.split("\n").map((line, index) => `${index + 1} | ${line}`).join("\n");
|
|
1535
|
+
}
|
|
1536
|
+
/**
|
|
1537
|
+
* Forces the model to call a single reporting tool and returns the validated
|
|
1538
|
+
* tool arguments, so a tool call doubles as structured output. Unlike
|
|
1539
|
+
* `response_format`-based structured output (xsai's `generateObject`), a
|
|
1540
|
+
* forced tool call works on any provider with function calling, and invalid
|
|
1541
|
+
* payloads are retried with validation feedback instead of failing outright.
|
|
1542
|
+
*/
|
|
1543
|
+
async function generateStructured(options) {
|
|
1544
|
+
const maxAttempts = options.maxAttempts ?? defaultMaxAttempts;
|
|
1545
|
+
const retryDelay = options.retryDelay ?? exponentialRetryDelay;
|
|
1546
|
+
const toolName = options.toolName ?? defaultToolName;
|
|
1547
|
+
const tool = rawTool({
|
|
1548
|
+
description: options.toolDescription ?? /* @__PURE__ */ getDescription(options.schema),
|
|
1549
|
+
execute: (input) => asRecord(input) ?? {},
|
|
1550
|
+
name: toolName,
|
|
1551
|
+
parameters: toolParametersFromSchema(options.schema),
|
|
1552
|
+
strict: true
|
|
1553
|
+
});
|
|
1554
|
+
let previousError;
|
|
1555
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
1556
|
+
options.signal?.throwIfAborted();
|
|
1557
|
+
let response;
|
|
1558
|
+
try {
|
|
1559
|
+
response = await generateText({
|
|
1560
|
+
abortSignal: options.signal,
|
|
1561
|
+
baseURL: options.model.provider.endpoint,
|
|
1562
|
+
headers: options.model.provider.headers,
|
|
1563
|
+
messages: options.createMessages(previousError ? retryFeedbackFrom(toolName, previousError) : void 0),
|
|
1564
|
+
model: options.model.id,
|
|
1565
|
+
parallelToolCalls: false,
|
|
1566
|
+
temperature: options.temperature ?? 0,
|
|
1567
|
+
toolChoice: {
|
|
1568
|
+
function: { name: toolName },
|
|
1569
|
+
type: "function"
|
|
1570
|
+
},
|
|
1571
|
+
tools: [tool]
|
|
1572
|
+
});
|
|
1573
|
+
} catch (error) {
|
|
1574
|
+
options.signal?.throwIfAborted();
|
|
1575
|
+
const callError = `Tool call failed before validation: ${errorMessageFrom(error) ?? String(error)}`;
|
|
1576
|
+
previousError = isRetriableHttpError(error) ? void 0 : callError;
|
|
1577
|
+
options.logger?.debug(`${options.operation} attempt ${attempt} failed while calling the model: ${callError}`);
|
|
1578
|
+
if (!isRetriableCallError(error) || attempt === maxAttempts) throw error;
|
|
1579
|
+
await setTimeout(retryDelay(attempt), void 0, { signal: options.signal });
|
|
1580
|
+
continue;
|
|
1581
|
+
}
|
|
1582
|
+
recordAttemptUsage(options, response);
|
|
1583
|
+
const result = parseStructuredResponse(options.schema, toolName, response);
|
|
1584
|
+
if (result.ok) return result.value;
|
|
1585
|
+
previousError = result.error;
|
|
1586
|
+
options.logger?.debug(`${options.operation} attempt ${attempt} returned an invalid structured result: ${previousError}`);
|
|
1587
|
+
if (!result.retriable || attempt === maxAttempts) throw new InvalidStructuredOutputError(`Invalid structured model response: ${previousError}`);
|
|
1588
|
+
await setTimeout(retryDelay(attempt), void 0, { signal: options.signal });
|
|
1589
|
+
}
|
|
1590
|
+
throw new InvalidStructuredOutputError("Model did not return a valid structured result");
|
|
1591
|
+
}
|
|
1592
|
+
function normalizeToolJsonSchema(schema) {
|
|
1593
|
+
const normalized = normalizeJsonSchemaDefinition(schema);
|
|
1594
|
+
return typeof normalized === "boolean" ? {} : normalized;
|
|
1595
|
+
}
|
|
1596
|
+
/** Converts a valibot schema into provider-compliant strict tool parameters. */
|
|
1597
|
+
function toolParametersFromSchema(schema) {
|
|
1598
|
+
return normalizeToolJsonSchema(toJsonSchema(schema));
|
|
1599
|
+
}
|
|
1600
|
+
function asRecord(value) {
|
|
1601
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
1602
|
+
}
|
|
1603
|
+
function exponentialRetryDelay(attempt) {
|
|
1604
|
+
return 500 * 2 ** (attempt - 1);
|
|
1605
|
+
}
|
|
1606
|
+
function isRetriableCallError(error) {
|
|
1607
|
+
if (!(error instanceof Error)) return true;
|
|
1608
|
+
if (isRetriableHttpError(error)) return true;
|
|
1609
|
+
return error.name === "InvalidToolCallError" || error.name === "InvalidToolInputError" || error.name === "ToolExecutionError";
|
|
1610
|
+
}
|
|
1611
|
+
function isRetriableHttpError(error) {
|
|
1612
|
+
if (!(error instanceof Error)) return false;
|
|
1613
|
+
const statusCode = "statusCode" in error && typeof error.statusCode === "number" ? error.statusCode : void 0;
|
|
1614
|
+
return statusCode !== void 0 && (statusCode >= 500 || [408, 429].includes(statusCode));
|
|
1615
|
+
}
|
|
1616
|
+
function normalizeJsonSchemaDefinition(schema) {
|
|
1617
|
+
if (typeof schema === "boolean") return schema;
|
|
1618
|
+
const normalized = { ...schema };
|
|
1619
|
+
delete normalized.$schema;
|
|
1620
|
+
if (normalized.type === "object") normalized.additionalProperties = false;
|
|
1621
|
+
if (normalized.properties) {
|
|
1622
|
+
normalized.properties = Object.fromEntries(Object.entries(normalized.properties).map(([key, propertySchema]) => [key, normalizeJsonSchemaDefinition(propertySchema)]));
|
|
1623
|
+
normalized.required = Object.keys(normalized.properties);
|
|
1624
|
+
}
|
|
1625
|
+
if (normalized.items) normalized.items = Array.isArray(normalized.items) ? normalized.items.map((item) => normalizeJsonSchemaDefinition(item)) : normalizeJsonSchemaDefinition(normalized.items);
|
|
1626
|
+
if (normalized.$defs) normalized.$defs = normalizeJsonSchemaMap(normalized.$defs);
|
|
1627
|
+
if (normalized.definitions) normalized.definitions = normalizeJsonSchemaMap(normalized.definitions);
|
|
1628
|
+
for (const key of [
|
|
1629
|
+
"allOf",
|
|
1630
|
+
"anyOf",
|
|
1631
|
+
"oneOf"
|
|
1632
|
+
]) if (normalized[key]) normalized[key] = normalized[key].map((item) => normalizeJsonSchemaDefinition(item));
|
|
1633
|
+
if (normalized.not) normalized.not = normalizeJsonSchemaDefinition(normalized.not);
|
|
1634
|
+
return normalized;
|
|
1635
|
+
}
|
|
1636
|
+
function normalizeJsonSchemaMap(map) {
|
|
1637
|
+
return Object.fromEntries(Object.entries(map).map(([key, schema]) => [key, normalizeJsonSchemaDefinition(schema)]));
|
|
1638
|
+
}
|
|
1639
|
+
function normalizeUsage(usage) {
|
|
1640
|
+
const record = asRecord(usage);
|
|
1641
|
+
if (!record) return;
|
|
1642
|
+
const normalized = {
|
|
1643
|
+
inputTokens: numberFromRecord(record, "inputTokens") ?? numberFromRecord(record, "input_tokens") ?? numberFromRecord(record, "prompt_tokens"),
|
|
1644
|
+
outputTokens: numberFromRecord(record, "outputTokens") ?? numberFromRecord(record, "output_tokens") ?? numberFromRecord(record, "completion_tokens"),
|
|
1645
|
+
totalTokens: numberFromRecord(record, "totalTokens") ?? numberFromRecord(record, "total_tokens")
|
|
1646
|
+
};
|
|
1647
|
+
return Object.values(normalized).some((value) => value !== void 0) ? normalized : void 0;
|
|
1648
|
+
}
|
|
1649
|
+
function numberFromRecord(record, key) {
|
|
1650
|
+
const value = record[key];
|
|
1651
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1652
|
+
}
|
|
1653
|
+
function parseStructuredResponse(schema, toolName, response) {
|
|
1654
|
+
if (response.finishReason === "content_filter") return {
|
|
1655
|
+
error: `${toolName} was not returned because the model finished with content_filter`,
|
|
1656
|
+
ok: false,
|
|
1657
|
+
retriable: false
|
|
1658
|
+
};
|
|
1659
|
+
if (response.finishReason === "length") return {
|
|
1660
|
+
error: `${toolName} was not returned completely because the model finished with length`,
|
|
1661
|
+
ok: false,
|
|
1662
|
+
retriable: true
|
|
1663
|
+
};
|
|
1664
|
+
const toolResults = response.toolResults.filter((result) => result.toolName === toolName);
|
|
1665
|
+
if (toolResults.length === 0) return {
|
|
1666
|
+
error: `Missing ${toolName} tool result; finishReason=${response.finishReason}`,
|
|
1667
|
+
ok: false,
|
|
1668
|
+
retriable: true
|
|
1669
|
+
};
|
|
1670
|
+
if (toolResults.length > 1) return {
|
|
1671
|
+
error: `Expected one ${toolName} tool result, received ${toolResults.length}`,
|
|
1672
|
+
ok: false,
|
|
1673
|
+
retriable: true
|
|
1674
|
+
};
|
|
1675
|
+
try {
|
|
1676
|
+
return {
|
|
1677
|
+
ok: true,
|
|
1678
|
+
value: parse(schema, toolResults[0].result)
|
|
1679
|
+
};
|
|
1680
|
+
} catch (error) {
|
|
1681
|
+
return {
|
|
1682
|
+
error: errorMessageFrom(error) ?? String(error),
|
|
1683
|
+
ok: false,
|
|
1684
|
+
retriable: true
|
|
1685
|
+
};
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
function recordAttemptUsage(options, response) {
|
|
1689
|
+
const usage = normalizeUsage(response.usage);
|
|
1690
|
+
if (!options.metering || !usage) return;
|
|
1691
|
+
options.metering.recordUsage({
|
|
1692
|
+
inputTokens: usage.inputTokens,
|
|
1693
|
+
metadata: { operation: options.operation },
|
|
1694
|
+
modelId: options.model.id,
|
|
1695
|
+
outputTokens: usage.outputTokens,
|
|
1696
|
+
providerId: options.model.provider.id,
|
|
1697
|
+
totalTokens: usage.totalTokens
|
|
1698
|
+
});
|
|
1699
|
+
}
|
|
1700
|
+
function retryFeedbackFrom(toolName, error) {
|
|
1701
|
+
return [
|
|
1702
|
+
"Your previous tool call could not be validated.",
|
|
1703
|
+
`Validation error: ${error}`,
|
|
1704
|
+
`Call ${toolName} again with arguments that exactly match the tool schema.`
|
|
1705
|
+
].join("\n");
|
|
1706
|
+
}
|
|
1707
|
+
//#endregion
|
|
49
1708
|
//#region src/agents/judge/agent.ts
|
|
50
|
-
const judgeFindingSchema = pipe(object({
|
|
51
|
-
confidence: pipe(picklist([
|
|
1709
|
+
const judgeFindingSchema = /* @__PURE__ */ pipe(/* @__PURE__ */ object({
|
|
1710
|
+
confidence: /* @__PURE__ */ pipe(/* @__PURE__ */ picklist([
|
|
52
1711
|
"high",
|
|
53
1712
|
"medium",
|
|
54
1713
|
"low"
|
|
55
|
-
]), description("Confidence in this finding. Use exactly \"low\", \"medium\", or \"high\" without punctuation.")),
|
|
56
|
-
line: pipe(number(), description([
|
|
1714
|
+
]), /* @__PURE__ */ description("Confidence in this finding. Use exactly \"low\", \"medium\", or \"high\" without punctuation.")),
|
|
1715
|
+
line: /* @__PURE__ */ pipe(/* @__PURE__ */ number(), /* @__PURE__ */ description([
|
|
57
1716
|
"Use the declaration line of the specific symbol being reported.",
|
|
58
1717
|
"Use the left-column line number from the numbered code block.",
|
|
59
1718
|
"Do not use a nearby caller line unless that caller is the symbol being reported."
|
|
60
1719
|
].join(" "))),
|
|
61
|
-
message: pipe(string(), description([
|
|
1720
|
+
message: /* @__PURE__ */ pipe(/* @__PURE__ */ string(), /* @__PURE__ */ description([
|
|
62
1721
|
"Mention the specific symbol being reported.",
|
|
63
1722
|
"Explain the rule-specific design or readability smell.",
|
|
64
1723
|
"Do not list unrelated symbol names in the message.",
|
|
65
1724
|
"Keep the message short."
|
|
66
1725
|
].join(" "))),
|
|
67
|
-
suggestion: pipe(string(), description([
|
|
1726
|
+
suggestion: /* @__PURE__ */ pipe(/* @__PURE__ */ string(), /* @__PURE__ */ description([
|
|
68
1727
|
"Provide one concrete remediation direction.",
|
|
69
1728
|
"Do not propose a code patch.",
|
|
70
1729
|
"Keep the suggestion under 35 words."
|
|
71
1730
|
].join(" ")))
|
|
72
|
-
}), description("One warning-level report for a rule-specific design or readability smell."));
|
|
73
|
-
const judgeResponseSchema = pipe(object({ findings: pipe(array(judgeFindingSchema), description("All warning-level findings. Return an empty array when there is no qualifying issue for the current rule.")) }), description("Report findings for this TypeScript file."));
|
|
1731
|
+
}), /* @__PURE__ */ description("One warning-level report for a rule-specific design or readability smell."));
|
|
1732
|
+
const judgeResponseSchema = /* @__PURE__ */ pipe(/* @__PURE__ */ object({ findings: /* @__PURE__ */ pipe(/* @__PURE__ */ array(judgeFindingSchema), /* @__PURE__ */ description("All warning-level findings. Return an empty array when there is no qualifying issue for the current rule.")) }), /* @__PURE__ */ description("Report findings for this TypeScript file."));
|
|
74
1733
|
function createJudgeMessages(source, retryFeedback, outputLanguage, prompt) {
|
|
75
1734
|
return [
|
|
76
1735
|
{
|
|
@@ -309,8 +1968,8 @@ function createRedundantBindingVerificationPrompt(candidates) {
|
|
|
309
1968
|
"</discovery-data>"
|
|
310
1969
|
].join("\n");
|
|
311
1970
|
}
|
|
312
|
-
const verificationResponseSchema = pipe(object({ decisions: pipe(array(object({
|
|
313
|
-
boundary: pipe(picklist([
|
|
1971
|
+
const verificationResponseSchema = /* @__PURE__ */ pipe(/* @__PURE__ */ object({ decisions: /* @__PURE__ */ pipe(/* @__PURE__ */ array(/* @__PURE__ */ object({
|
|
1972
|
+
boundary: /* @__PURE__ */ pipe(/* @__PURE__ */ picklist([
|
|
314
1973
|
"none",
|
|
315
1974
|
"snapshot-or-restoration",
|
|
316
1975
|
"receiver",
|
|
@@ -319,24 +1978,24 @@ const verificationResponseSchema = pipe(object({ decisions: pipe(array(object({
|
|
|
319
1978
|
"mutable-work-state",
|
|
320
1979
|
"type-or-domain",
|
|
321
1980
|
"uncertain"
|
|
322
|
-
]), description("The concrete semantic boundary, or \"none\" only when no boundary exists.")),
|
|
323
|
-
confidence: pipe(picklist([
|
|
1981
|
+
]), /* @__PURE__ */ description("The concrete semantic boundary, or \"none\" only when no boundary exists.")),
|
|
1982
|
+
confidence: /* @__PURE__ */ pipe(/* @__PURE__ */ picklist([
|
|
324
1983
|
"high",
|
|
325
1984
|
"medium",
|
|
326
1985
|
"low"
|
|
327
|
-
]), description("Confidence in this verification decision.")),
|
|
328
|
-
initializer: pipe(picklist([
|
|
1986
|
+
]), /* @__PURE__ */ description("Confidence in this verification decision.")),
|
|
1987
|
+
initializer: /* @__PURE__ */ pipe(/* @__PURE__ */ picklist([
|
|
329
1988
|
"identifier",
|
|
330
1989
|
"static-member-access",
|
|
331
1990
|
"indexed-or-dynamic",
|
|
332
1991
|
"computed-or-constructed",
|
|
333
1992
|
"uncertain"
|
|
334
|
-
]), description("Classify the complete initializer. Bracket access belongs to \"indexed-or-dynamic\", never \"static-member-access\".")),
|
|
335
|
-
line: pipe(number(), description("One candidate declaration line supplied by discovery. Never add another line.")),
|
|
336
|
-
message: pipe(string(), description("Explain why the candidate qualifies or which exclusion rejects it.")),
|
|
337
|
-
safeSubstitution: pipe(boolean(), description("True only when every use can be replaced by the exact initializer without semantic change.")),
|
|
338
|
-
suggestion: pipe(string(), description("For accepted candidates, give a direct-use remediation under 35 words; otherwise briefly state the preserved boundary."))
|
|
339
|
-
})), description("One verification decision per supplied candidate line. Omit no candidate and add no line.")) }), description("Strict verification decisions for discovered rebinding candidates."));
|
|
1993
|
+
]), /* @__PURE__ */ description("Classify the complete initializer. Bracket access belongs to \"indexed-or-dynamic\", never \"static-member-access\".")),
|
|
1994
|
+
line: /* @__PURE__ */ pipe(/* @__PURE__ */ number(), /* @__PURE__ */ description("One candidate declaration line supplied by discovery. Never add another line.")),
|
|
1995
|
+
message: /* @__PURE__ */ pipe(/* @__PURE__ */ string(), /* @__PURE__ */ description("Explain why the candidate qualifies or which exclusion rejects it.")),
|
|
1996
|
+
safeSubstitution: /* @__PURE__ */ pipe(/* @__PURE__ */ boolean(), /* @__PURE__ */ description("True only when every use can be replaced by the exact initializer without semantic change.")),
|
|
1997
|
+
suggestion: /* @__PURE__ */ pipe(/* @__PURE__ */ string(), /* @__PURE__ */ description("For accepted candidates, give a direct-use remediation under 35 words; otherwise briefly state the preserved boundary."))
|
|
1998
|
+
})), /* @__PURE__ */ description("One verification decision per supplied candidate line. Omit no candidate and add no line.")) }), /* @__PURE__ */ description("Strict verification decisions for discovered rebinding candidates."));
|
|
340
1999
|
function acceptedVerificationDecisions(decisions) {
|
|
341
2000
|
return decisions.filter((decision) => (decision.initializer === "identifier" || decision.initializer === "static-member-access") && decision.boundary === "none" && decision.safeSubstitution).map((decision) => ({
|
|
342
2001
|
confidence: decision.confidence,
|
|
@@ -654,4 +2313,4 @@ const examplePlugin = definePlugin({
|
|
|
654
2313
|
}
|
|
655
2314
|
});
|
|
656
2315
|
//#endregion
|
|
657
|
-
export { createJudgeMessages, createReportFindingsToolParameters, examplePlugin as default, examplePlugin, inlineMiniatureNormalizerPrompt, inlineMiniatureNormalizerRule, judgeFindingSchema, judgeResponseSchema, privateSchemaToolkitPrompt, privateSchemaToolkitRule, redundantBindingPrompt, redundantBindingRule, redundantJsdocPrompt, redundantJsdocRule, trivialWrapperStackPrompt, trivialWrapperStackRule, vacuousFunctionPrompt, vacuousFunctionRule };
|
|
2316
|
+
export { createJudgeMessages, createReportFindingsToolParameters, examplePlugin as default, examplePlugin, inlineMiniatureNormalizerPrompt, inlineMiniatureNormalizerRule, judgeFindingSchema, judgeResponseSchema, privateSchemaToolkitPrompt, privateSchemaToolkitRule, redundantBindingPrompt, redundantBindingRule, redundantJsdocPrompt, redundantJsdocRule, dist_exports as t, trivialWrapperStackPrompt, trivialWrapperStackRule, vacuousFunctionPrompt, vacuousFunctionRule };
|