@ax-llm/ax 10.0.42 → 10.0.44
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/index.cjs +547 -189
- package/index.cjs.map +1 -1
- package/index.d.cts +77 -5
- package/index.d.ts +77 -5
- package/index.js +549 -197
- package/index.js.map +1 -1
- package/package.json +2 -3
package/index.cjs
CHANGED
|
@@ -58,6 +58,13 @@ __export(index_exports, {
|
|
|
58
58
|
AxAIOpenAIModel: () => AxAIOpenAIModel,
|
|
59
59
|
AxAIReka: () => AxAIReka,
|
|
60
60
|
AxAIRekaModel: () => AxAIRekaModel,
|
|
61
|
+
AxAIServiceAuthenticationError: () => AxAIServiceAuthenticationError,
|
|
62
|
+
AxAIServiceError: () => AxAIServiceError,
|
|
63
|
+
AxAIServiceNetworkError: () => AxAIServiceNetworkError,
|
|
64
|
+
AxAIServiceResponseError: () => AxAIServiceResponseError,
|
|
65
|
+
AxAIServiceStatusError: () => AxAIServiceStatusError,
|
|
66
|
+
AxAIServiceStreamTerminatedError: () => AxAIServiceStreamTerminatedError,
|
|
67
|
+
AxAIServiceTimeoutError: () => AxAIServiceTimeoutError,
|
|
61
68
|
AxAITogether: () => AxAITogether,
|
|
62
69
|
AxAgent: () => AxAgent,
|
|
63
70
|
AxApacheTika: () => AxApacheTika,
|
|
@@ -182,15 +189,21 @@ var import_api = require("@opentelemetry/api");
|
|
|
182
189
|
// util/sse.ts
|
|
183
190
|
var import_web = require("stream/web");
|
|
184
191
|
var SSEParser = class extends import_web.TransformStream {
|
|
185
|
-
|
|
192
|
+
buffer = "";
|
|
193
|
+
currentEvent = { rawData: "" };
|
|
194
|
+
dataParser;
|
|
195
|
+
onError;
|
|
196
|
+
constructor(options = {}) {
|
|
186
197
|
super({
|
|
187
198
|
transform: (chunk, controller) => this.handleChunk(chunk, controller),
|
|
188
199
|
flush: (controller) => this.handleFlush(controller)
|
|
189
200
|
});
|
|
190
|
-
this.dataParser = dataParser;
|
|
201
|
+
this.dataParser = options.dataParser || JSON.parse;
|
|
202
|
+
this.onError = options.onError || ((error, rawData) => {
|
|
203
|
+
console.warn("Failed to parse event data:", error);
|
|
204
|
+
console.log("Raw data that failed to parse:", rawData);
|
|
205
|
+
});
|
|
191
206
|
}
|
|
192
|
-
buffer = "";
|
|
193
|
-
currentEvent = { rawData: "" };
|
|
194
207
|
handleChunk(chunk, controller) {
|
|
195
208
|
this.buffer += chunk;
|
|
196
209
|
this.processBuffer(controller);
|
|
@@ -198,24 +211,28 @@ var SSEParser = class extends import_web.TransformStream {
|
|
|
198
211
|
handleFlush(controller) {
|
|
199
212
|
this.processBuffer(controller);
|
|
200
213
|
if (this.currentEvent.rawData) {
|
|
201
|
-
this.
|
|
214
|
+
this.processEvent(controller);
|
|
202
215
|
}
|
|
203
216
|
}
|
|
204
217
|
processBuffer(controller) {
|
|
205
|
-
const
|
|
218
|
+
const normalizedBuffer = this.buffer.replace(/\r\n|\r/g, "\n");
|
|
219
|
+
const lines = normalizedBuffer.split("\n");
|
|
206
220
|
this.buffer = lines.pop() || "";
|
|
207
221
|
for (const line of lines) {
|
|
208
|
-
if (line
|
|
209
|
-
this.
|
|
222
|
+
if (line === "") {
|
|
223
|
+
this.processEvent(controller);
|
|
210
224
|
} else {
|
|
211
225
|
this.parseLine(line);
|
|
212
226
|
}
|
|
213
227
|
}
|
|
214
228
|
}
|
|
215
229
|
parseLine(line) {
|
|
230
|
+
if (line.startsWith(":")) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
216
233
|
const colonIndex = line.indexOf(":");
|
|
217
234
|
if (colonIndex === -1) {
|
|
218
|
-
this.currentEvent.rawData += this.currentEvent.rawData ? "\n"
|
|
235
|
+
this.currentEvent.rawData += (this.currentEvent.rawData && !this.currentEvent.rawData.endsWith("\n") ? "\n" : "") + line.trim();
|
|
219
236
|
return;
|
|
220
237
|
}
|
|
221
238
|
const field = line.slice(0, colonIndex).trim();
|
|
@@ -225,7 +242,7 @@ var SSEParser = class extends import_web.TransformStream {
|
|
|
225
242
|
this.currentEvent.event = value;
|
|
226
243
|
break;
|
|
227
244
|
case "data":
|
|
228
|
-
this.currentEvent.rawData += this.currentEvent.rawData
|
|
245
|
+
this.currentEvent.rawData += (this.currentEvent.rawData && !this.currentEvent.rawData.endsWith("\n") ? "\n" : "") + value;
|
|
229
246
|
break;
|
|
230
247
|
case "id":
|
|
231
248
|
this.currentEvent.id = value;
|
|
@@ -239,21 +256,20 @@ var SSEParser = class extends import_web.TransformStream {
|
|
|
239
256
|
}
|
|
240
257
|
}
|
|
241
258
|
}
|
|
242
|
-
|
|
259
|
+
processEvent(controller) {
|
|
243
260
|
if (this.currentEvent.rawData) {
|
|
244
|
-
if (this.currentEvent.
|
|
261
|
+
if (!this.currentEvent.event) {
|
|
262
|
+
this.currentEvent.event = "message";
|
|
263
|
+
}
|
|
264
|
+
if (this.currentEvent.rawData.trim() === "[DONE]") {
|
|
265
|
+
this.currentEvent = { rawData: "" };
|
|
245
266
|
return;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
console.log(
|
|
253
|
-
"Raw data that failed to parse:",
|
|
254
|
-
this.currentEvent.rawData
|
|
255
|
-
);
|
|
256
|
-
}
|
|
267
|
+
}
|
|
268
|
+
try {
|
|
269
|
+
const parsedData = this.dataParser(this.currentEvent.rawData);
|
|
270
|
+
controller.enqueue(parsedData);
|
|
271
|
+
} catch (e) {
|
|
272
|
+
this.onError(e, this.currentEvent.rawData);
|
|
257
273
|
}
|
|
258
274
|
this.currentEvent = { rawData: "" };
|
|
259
275
|
}
|
|
@@ -290,52 +306,305 @@ var TextDecoderStreamPolyfill = class extends import_web2.TransformStream {
|
|
|
290
306
|
};
|
|
291
307
|
|
|
292
308
|
// util/apicall.ts
|
|
309
|
+
var defaultRetryConfig = {
|
|
310
|
+
maxRetries: 3,
|
|
311
|
+
initialDelayMs: 1e3,
|
|
312
|
+
maxDelayMs: 6e4,
|
|
313
|
+
// Increased to 60 seconds
|
|
314
|
+
backoffFactor: 2,
|
|
315
|
+
retryableStatusCodes: [500, 408, 429, 502, 503, 504]
|
|
316
|
+
};
|
|
317
|
+
var defaultTimeoutMs = 3e4;
|
|
293
318
|
var textDecoderStream = import_web3.TextDecoderStream ?? TextDecoderStreamPolyfill;
|
|
319
|
+
var AxAIServiceError = class extends Error {
|
|
320
|
+
constructor(message, url, requestBody, context = {}) {
|
|
321
|
+
super(message);
|
|
322
|
+
this.url = url;
|
|
323
|
+
this.requestBody = requestBody;
|
|
324
|
+
this.context = context;
|
|
325
|
+
this.name = "AxAIServiceError";
|
|
326
|
+
this.timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
327
|
+
this.errorId = crypto.randomUUID();
|
|
328
|
+
}
|
|
329
|
+
timestamp;
|
|
330
|
+
errorId;
|
|
331
|
+
toString() {
|
|
332
|
+
return `${this.name} [${this.errorId}]: ${this.message}
|
|
333
|
+
Timestamp: ${this.timestamp}
|
|
334
|
+
URL: ${this.url}${this.requestBody ? `
|
|
335
|
+
Request Body: ${JSON.stringify(this.requestBody, null, 2)}` : ""}${this.context ? `
|
|
336
|
+
Context: ${JSON.stringify(this.context, null, 2)}` : ""}`;
|
|
337
|
+
}
|
|
338
|
+
toJSON() {
|
|
339
|
+
return {
|
|
340
|
+
name: this.name,
|
|
341
|
+
errorId: this.errorId,
|
|
342
|
+
message: this.message,
|
|
343
|
+
timestamp: this.timestamp,
|
|
344
|
+
url: this.url,
|
|
345
|
+
requestBody: this.requestBody,
|
|
346
|
+
context: this.context,
|
|
347
|
+
stack: this.stack
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
var AxAIServiceStatusError = class extends AxAIServiceError {
|
|
352
|
+
constructor(status, statusText, url, requestBody, context) {
|
|
353
|
+
super(`HTTP ${status} - ${statusText}`, url, requestBody, {
|
|
354
|
+
httpStatus: status,
|
|
355
|
+
httpStatusText: statusText,
|
|
356
|
+
...context
|
|
357
|
+
});
|
|
358
|
+
this.status = status;
|
|
359
|
+
this.statusText = statusText;
|
|
360
|
+
this.name = "AxAIServiceStatusError";
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
var AxAIServiceNetworkError = class extends AxAIServiceError {
|
|
364
|
+
constructor(originalError, url, requestBody, context) {
|
|
365
|
+
super(`Network Error: ${originalError.message}`, url, requestBody, {
|
|
366
|
+
originalErrorName: originalError.name,
|
|
367
|
+
originalErrorStack: originalError.stack,
|
|
368
|
+
...context
|
|
369
|
+
});
|
|
370
|
+
this.originalError = originalError;
|
|
371
|
+
this.name = "AxAIServiceNetworkError";
|
|
372
|
+
this.stack = originalError.stack;
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
var AxAIServiceResponseError = class extends AxAIServiceError {
|
|
376
|
+
constructor(message, url, requestBody, context) {
|
|
377
|
+
super(message, url, requestBody, context);
|
|
378
|
+
this.name = "AxAIServiceResponseError";
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
var AxAIServiceStreamTerminatedError = class extends AxAIServiceError {
|
|
382
|
+
constructor(url, requestBody, lastChunk, context) {
|
|
383
|
+
super("Stream terminated unexpectedly by remote host", url, requestBody, {
|
|
384
|
+
lastChunk,
|
|
385
|
+
...context
|
|
386
|
+
});
|
|
387
|
+
this.lastChunk = lastChunk;
|
|
388
|
+
this.name = "AxAIServiceStreamTerminatedError";
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
var AxAIServiceTimeoutError = class extends AxAIServiceError {
|
|
392
|
+
constructor(url, timeoutMs, requestBody, context) {
|
|
393
|
+
super(`Request timeout after ${timeoutMs}ms`, url, requestBody, {
|
|
394
|
+
timeoutMs,
|
|
395
|
+
...context
|
|
396
|
+
});
|
|
397
|
+
this.name = "AxAIServiceTimeoutError";
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
var AxAIServiceAuthenticationError = class extends AxAIServiceError {
|
|
401
|
+
constructor(url, requestBody, context) {
|
|
402
|
+
super("Authentication failed", url, requestBody, context);
|
|
403
|
+
this.name = "AxAIServiceAuthenticationError";
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
function calculateRetryDelay(attempt, config) {
|
|
407
|
+
const delay = Math.min(
|
|
408
|
+
config.maxDelayMs,
|
|
409
|
+
config.initialDelayMs * Math.pow(config.backoffFactor, attempt)
|
|
410
|
+
);
|
|
411
|
+
return delay * (0.75 + Math.random() * 0.5);
|
|
412
|
+
}
|
|
413
|
+
function createRequestMetrics() {
|
|
414
|
+
return {
|
|
415
|
+
startTime: Date.now(),
|
|
416
|
+
retryCount: 0
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
function updateRetryMetrics(metrics) {
|
|
420
|
+
metrics.retryCount++;
|
|
421
|
+
metrics.lastRetryTime = Date.now();
|
|
422
|
+
}
|
|
294
423
|
var apiCall = async (api, json) => {
|
|
424
|
+
const retryConfig = { ...defaultRetryConfig, ...api.retry };
|
|
425
|
+
const timeoutMs = api.timeout ?? defaultTimeoutMs;
|
|
426
|
+
const metrics = createRequestMetrics();
|
|
295
427
|
const baseUrl = new URL(process.env["PROXY"] ?? api.url);
|
|
296
428
|
const apiPath = import_path.default.join(baseUrl.pathname, api.name ?? "/", baseUrl.search);
|
|
297
429
|
const apiUrl = new URL(apiPath, baseUrl);
|
|
430
|
+
const requestId = crypto.randomUUID();
|
|
298
431
|
if (api.span?.isRecording()) {
|
|
299
432
|
api.span.setAttributes({
|
|
300
433
|
"http.request.method": api.put ? "PUT" : "POST",
|
|
301
|
-
"url.full": apiUrl.href
|
|
434
|
+
"url.full": apiUrl.href,
|
|
435
|
+
"request.id": requestId,
|
|
436
|
+
"request.startTime": metrics.startTime
|
|
302
437
|
});
|
|
303
438
|
}
|
|
304
|
-
let
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
439
|
+
let attempt = 0;
|
|
440
|
+
while (true) {
|
|
441
|
+
const controller = new AbortController();
|
|
442
|
+
let timeoutId = setTimeout(() => {
|
|
443
|
+
controller.abort("Request timeout");
|
|
444
|
+
}, timeoutMs);
|
|
445
|
+
try {
|
|
446
|
+
const res = await (api.fetch ?? fetch)(apiUrl, {
|
|
447
|
+
method: api.put ? "PUT" : "POST",
|
|
448
|
+
headers: {
|
|
449
|
+
"Content-Type": "application/json",
|
|
450
|
+
"X-Request-ID": requestId,
|
|
451
|
+
"X-Retry-Count": attempt.toString(),
|
|
452
|
+
...api.headers
|
|
453
|
+
},
|
|
454
|
+
body: JSON.stringify(json),
|
|
455
|
+
signal: controller.signal
|
|
456
|
+
});
|
|
457
|
+
clearTimeout(timeoutId);
|
|
458
|
+
if (res.status === 401 || res.status === 403) {
|
|
459
|
+
throw new AxAIServiceAuthenticationError(apiUrl.href, json, { metrics });
|
|
460
|
+
}
|
|
461
|
+
if (res.status >= 400 && attempt < retryConfig.maxRetries && retryConfig.retryableStatusCodes.includes(res.status)) {
|
|
462
|
+
const delay = calculateRetryDelay(attempt, retryConfig);
|
|
463
|
+
attempt++;
|
|
464
|
+
updateRetryMetrics(metrics);
|
|
465
|
+
if (api.span?.isRecording()) {
|
|
466
|
+
api.span.addEvent("retry", {
|
|
467
|
+
attempt,
|
|
468
|
+
delay,
|
|
469
|
+
status: res.status,
|
|
470
|
+
"metrics.startTime": metrics.startTime,
|
|
471
|
+
"metrics.retryCount": metrics.retryCount,
|
|
472
|
+
"metrics.lastRetryTime": metrics.lastRetryTime
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
clearTimeout(timeoutId);
|
|
476
|
+
continue;
|
|
477
|
+
}
|
|
478
|
+
if (res.status >= 400) {
|
|
479
|
+
throw new AxAIServiceStatusError(
|
|
480
|
+
res.status,
|
|
481
|
+
res.statusText,
|
|
482
|
+
apiUrl.href,
|
|
483
|
+
json,
|
|
484
|
+
{ metrics }
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
if (!api.stream) {
|
|
488
|
+
const resJson = await res.json();
|
|
489
|
+
if (api.span?.isRecording()) {
|
|
490
|
+
api.span.setAttributes({
|
|
491
|
+
"response.time": Date.now() - metrics.startTime,
|
|
492
|
+
"response.retries": metrics.retryCount
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
return resJson;
|
|
496
|
+
}
|
|
497
|
+
if (!res.body) {
|
|
498
|
+
throw new AxAIServiceResponseError(
|
|
499
|
+
"Response body is null",
|
|
500
|
+
apiUrl.href,
|
|
501
|
+
json,
|
|
502
|
+
{ metrics }
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
let lastChunk;
|
|
506
|
+
let chunkCount = 0;
|
|
507
|
+
const trackingStream = new TransformStream({
|
|
508
|
+
transform(chunk, controller2) {
|
|
509
|
+
lastChunk = chunk;
|
|
510
|
+
chunkCount++;
|
|
511
|
+
metrics.streamChunks = chunkCount;
|
|
512
|
+
metrics.lastChunkTime = Date.now();
|
|
513
|
+
controller2.enqueue(chunk);
|
|
514
|
+
},
|
|
515
|
+
flush(controller2) {
|
|
516
|
+
if (api.span?.isRecording()) {
|
|
517
|
+
api.span.setAttributes({
|
|
518
|
+
"stream.chunks": chunkCount,
|
|
519
|
+
"stream.duration": Date.now() - metrics.startTime,
|
|
520
|
+
"response.retries": metrics.retryCount
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
controller2.terminate();
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
const wrappedStream = new import_web3.ReadableStream({
|
|
527
|
+
start(controller2) {
|
|
528
|
+
const reader = res.body.pipeThrough(new textDecoderStream()).pipeThrough(new SSEParser()).pipeThrough(trackingStream).getReader();
|
|
529
|
+
async function read() {
|
|
530
|
+
try {
|
|
531
|
+
while (true) {
|
|
532
|
+
const { done, value } = await reader.read();
|
|
533
|
+
if (done) {
|
|
534
|
+
controller2.close();
|
|
535
|
+
break;
|
|
536
|
+
} else {
|
|
537
|
+
controller2.enqueue(value);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
} catch (e) {
|
|
541
|
+
const error = e;
|
|
542
|
+
const streamMetrics = {
|
|
543
|
+
...metrics,
|
|
544
|
+
streamDuration: Date.now() - metrics.startTime
|
|
545
|
+
};
|
|
546
|
+
if (error.name === "AbortError" || error.message?.includes("aborted")) {
|
|
547
|
+
controller2.error(
|
|
548
|
+
new AxAIServiceStreamTerminatedError(
|
|
549
|
+
apiUrl.href,
|
|
550
|
+
json,
|
|
551
|
+
lastChunk,
|
|
552
|
+
{ streamMetrics }
|
|
553
|
+
)
|
|
554
|
+
);
|
|
555
|
+
} else {
|
|
556
|
+
controller2.error(
|
|
557
|
+
new AxAIServiceResponseError(
|
|
558
|
+
`Stream processing error: ${error.message}`,
|
|
559
|
+
apiUrl.href,
|
|
560
|
+
json,
|
|
561
|
+
{ streamMetrics }
|
|
562
|
+
)
|
|
563
|
+
);
|
|
564
|
+
}
|
|
565
|
+
} finally {
|
|
566
|
+
reader.releaseLock();
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
read();
|
|
570
|
+
}
|
|
571
|
+
});
|
|
572
|
+
return wrappedStream;
|
|
573
|
+
} catch (error) {
|
|
574
|
+
clearTimeout(timeoutId);
|
|
575
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
576
|
+
throw new AxAIServiceTimeoutError(apiUrl.href, timeoutMs, json, {
|
|
577
|
+
metrics
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
if (api.span?.isRecording()) {
|
|
581
|
+
api.span.recordException(error);
|
|
582
|
+
api.span.setAttributes({
|
|
583
|
+
"error.time": Date.now() - metrics.startTime,
|
|
584
|
+
"error.retries": metrics.retryCount
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
if (error instanceof AxAIServiceNetworkError && attempt < retryConfig.maxRetries) {
|
|
588
|
+
const delay = calculateRetryDelay(attempt, retryConfig);
|
|
589
|
+
attempt++;
|
|
590
|
+
updateRetryMetrics(metrics);
|
|
591
|
+
if (api.span?.isRecording()) {
|
|
592
|
+
api.span.addEvent("retry", {
|
|
593
|
+
attempt,
|
|
594
|
+
delay,
|
|
595
|
+
error: error.message,
|
|
596
|
+
"metrics.startTime": metrics.startTime,
|
|
597
|
+
"metrics.retryCount": metrics.retryCount,
|
|
598
|
+
"metrics.lastRetryTime": metrics.lastRetryTime
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
continue;
|
|
602
|
+
}
|
|
603
|
+
if (error instanceof AxAIServiceError) {
|
|
604
|
+
error.context["metrics"] = metrics;
|
|
605
|
+
}
|
|
606
|
+
throw error;
|
|
333
607
|
}
|
|
334
|
-
const reqBody = JSON.stringify(json, null, 2);
|
|
335
|
-
throw new Error(
|
|
336
|
-
`API Response Error: ${apiUrl.href}, ${e}
|
|
337
|
-
Request Body: ${reqBody}`
|
|
338
|
-
);
|
|
339
608
|
}
|
|
340
609
|
};
|
|
341
610
|
|
|
@@ -3583,9 +3852,6 @@ var assertStreamingAssertions = (asserts, values, xstate, content, final) => {
|
|
|
3583
3852
|
}
|
|
3584
3853
|
};
|
|
3585
3854
|
|
|
3586
|
-
// dsp/extract.ts
|
|
3587
|
-
var import_json5 = __toESM(require("json5"), 1);
|
|
3588
|
-
|
|
3589
3855
|
// dsp/datetime.ts
|
|
3590
3856
|
var import_moment_timezone = __toESM(require("moment-timezone"), 1);
|
|
3591
3857
|
|
|
@@ -3616,104 +3882,143 @@ var import_crypto = require("crypto");
|
|
|
3616
3882
|
var SignatureParser = class {
|
|
3617
3883
|
input;
|
|
3618
3884
|
position;
|
|
3885
|
+
currentFieldName = null;
|
|
3619
3886
|
constructor(input) {
|
|
3620
3887
|
this.input = input;
|
|
3621
3888
|
this.position = 0;
|
|
3622
3889
|
}
|
|
3623
3890
|
parse() {
|
|
3624
|
-
|
|
3625
|
-
const optionalDesc = this.parseParsedString();
|
|
3626
|
-
this.skipWhitespace();
|
|
3627
|
-
const inputs = this.parseInputParsedFieldList();
|
|
3628
|
-
this.skipWhitespace();
|
|
3629
|
-
this.expect("->");
|
|
3630
|
-
this.skipWhitespace();
|
|
3631
|
-
const outputs = this.parseOutputParsedFieldList();
|
|
3632
|
-
return {
|
|
3633
|
-
desc: optionalDesc?.trim(),
|
|
3634
|
-
inputs,
|
|
3635
|
-
outputs
|
|
3636
|
-
};
|
|
3637
|
-
}
|
|
3638
|
-
parseInputParsedFieldList() {
|
|
3639
|
-
const fields = [];
|
|
3640
|
-
fields.push(this.parseInputParsedField());
|
|
3641
|
-
while (this.match(",")) {
|
|
3891
|
+
try {
|
|
3642
3892
|
this.skipWhitespace();
|
|
3643
|
-
|
|
3644
|
-
}
|
|
3645
|
-
return fields;
|
|
3646
|
-
}
|
|
3647
|
-
parseOutputParsedFieldList() {
|
|
3648
|
-
const fields = [];
|
|
3649
|
-
fields.push(this.parseOutputParsedField());
|
|
3650
|
-
while (this.match(",")) {
|
|
3893
|
+
const optionalDesc = this.parseParsedString();
|
|
3651
3894
|
this.skipWhitespace();
|
|
3652
|
-
|
|
3653
|
-
}
|
|
3654
|
-
return fields;
|
|
3655
|
-
}
|
|
3656
|
-
parseInputParsedField() {
|
|
3657
|
-
this.skipWhitespace();
|
|
3658
|
-
const name = this.parseParsedIdentifier();
|
|
3659
|
-
const isOptional = this.match("?");
|
|
3660
|
-
let type;
|
|
3661
|
-
if (this.match(":")) {
|
|
3895
|
+
const inputs = this.parseFieldList(this.parseField.bind(this), "input");
|
|
3662
3896
|
this.skipWhitespace();
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3897
|
+
if (this.position >= this.input.length) {
|
|
3898
|
+
throw new Error(
|
|
3899
|
+
'Incomplete signature: Missing output section. Expected "->" followed by output fields'
|
|
3900
|
+
);
|
|
3901
|
+
}
|
|
3902
|
+
this.expect("->");
|
|
3903
|
+
this.skipWhitespace();
|
|
3904
|
+
if (this.position >= this.input.length) {
|
|
3905
|
+
throw new Error(
|
|
3906
|
+
'Incomplete signature: No output fields specified after "->"'
|
|
3907
|
+
);
|
|
3908
|
+
}
|
|
3909
|
+
const outputs = this.parseFieldList(this.parseField.bind(this), "output");
|
|
3910
|
+
return {
|
|
3911
|
+
desc: optionalDesc?.trim(),
|
|
3912
|
+
inputs,
|
|
3913
|
+
outputs
|
|
3914
|
+
};
|
|
3915
|
+
} catch (error) {
|
|
3916
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
3917
|
+
const context = this.getErrorContext();
|
|
3918
|
+
throw new Error(`${errorMessage}
|
|
3919
|
+
${context}`);
|
|
3920
|
+
}
|
|
3921
|
+
}
|
|
3922
|
+
getErrorContext() {
|
|
3923
|
+
const start = Math.max(0, this.position - 20);
|
|
3924
|
+
const end = Math.min(this.input.length, this.position + 20);
|
|
3925
|
+
const before = this.input.slice(start, this.position);
|
|
3926
|
+
const after = this.input.slice(this.position, end);
|
|
3927
|
+
const pointer = " ".repeat(before.length) + "^";
|
|
3928
|
+
return `Near position ${this.position}:
|
|
3929
|
+
${before}${after}
|
|
3930
|
+
${pointer}`;
|
|
3931
|
+
}
|
|
3932
|
+
parseFieldList(parseFieldFn, section) {
|
|
3933
|
+
const fields = [];
|
|
3934
|
+
this.skipWhitespace();
|
|
3935
|
+
if (this.position >= this.input.length) {
|
|
3936
|
+
throw new Error(`Empty ${section} section: Expected at least one field`);
|
|
3937
|
+
}
|
|
3938
|
+
try {
|
|
3939
|
+
fields.push(parseFieldFn());
|
|
3940
|
+
} catch (error) {
|
|
3941
|
+
throw new Error(
|
|
3942
|
+
`Invalid first ${section} field: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
3943
|
+
);
|
|
3666
3944
|
}
|
|
3667
3945
|
this.skipWhitespace();
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3946
|
+
while (this.position < this.input.length) {
|
|
3947
|
+
if (this.input[this.position] === "-" && this.input[this.position + 1] === ">") {
|
|
3948
|
+
break;
|
|
3949
|
+
}
|
|
3950
|
+
if (this.match(",")) {
|
|
3951
|
+
this.skipWhitespace();
|
|
3952
|
+
if (this.position >= this.input.length) {
|
|
3953
|
+
throw new Error(
|
|
3954
|
+
`Unexpected end of input after comma in ${section} section`
|
|
3955
|
+
);
|
|
3956
|
+
}
|
|
3957
|
+
try {
|
|
3958
|
+
fields.push(parseFieldFn());
|
|
3959
|
+
} catch (error) {
|
|
3960
|
+
throw new Error(
|
|
3961
|
+
`Invalid ${section} field after comma: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
3962
|
+
);
|
|
3963
|
+
}
|
|
3964
|
+
this.skipWhitespace();
|
|
3965
|
+
} else {
|
|
3966
|
+
break;
|
|
3967
|
+
}
|
|
3968
|
+
}
|
|
3969
|
+
return fields;
|
|
3675
3970
|
}
|
|
3676
|
-
|
|
3971
|
+
parseField() {
|
|
3677
3972
|
this.skipWhitespace();
|
|
3678
3973
|
const name = this.parseParsedIdentifier();
|
|
3974
|
+
this.currentFieldName = name;
|
|
3679
3975
|
const isOptional = this.match("?");
|
|
3976
|
+
let type;
|
|
3680
3977
|
this.skipWhitespace();
|
|
3681
3978
|
if (this.match(":")) {
|
|
3682
3979
|
this.skipWhitespace();
|
|
3683
3980
|
if (this.match("class")) {
|
|
3684
3981
|
const isArray = this.match("[]");
|
|
3685
3982
|
this.skipWhitespace();
|
|
3686
|
-
const
|
|
3687
|
-
if (!
|
|
3983
|
+
const desc2 = this.parseParsedString();
|
|
3984
|
+
if (!desc2) {
|
|
3688
3985
|
throw new Error(
|
|
3689
|
-
"Expected
|
|
3986
|
+
`Field "${name}": Expected class names in quotes after "class" type. Example: class "MyClass1, MyClass2"`
|
|
3690
3987
|
);
|
|
3691
3988
|
}
|
|
3692
|
-
const
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
}
|
|
3989
|
+
const classes = desc2.split(/[,\s]+/).map((s) => s.trim()).filter((s) => s.length > 0);
|
|
3990
|
+
if (classes.length === 0) {
|
|
3991
|
+
throw new Error(
|
|
3992
|
+
`Field "${name}": Empty class list provided. At least one class name is required`
|
|
3993
|
+
);
|
|
3994
|
+
}
|
|
3995
|
+
type = { name: "class", isArray, classes };
|
|
3698
3996
|
} else {
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
};
|
|
3997
|
+
try {
|
|
3998
|
+
const typeName = this.parseTypeNotClass();
|
|
3999
|
+
const isArray = this.match("[]");
|
|
4000
|
+
type = { name: typeName, isArray };
|
|
4001
|
+
} catch (error) {
|
|
4002
|
+
throw new Error(
|
|
4003
|
+
`Field "${name}": ${error instanceof Error ? error.message : "Unknown error"}`
|
|
4004
|
+
);
|
|
4005
|
+
}
|
|
3709
4006
|
}
|
|
4007
|
+
}
|
|
4008
|
+
this.skipWhitespace();
|
|
4009
|
+
const desc = this.parseParsedString();
|
|
4010
|
+
if (type?.name === "class") {
|
|
4011
|
+
return {
|
|
4012
|
+
name,
|
|
4013
|
+
desc: desc?.trim(),
|
|
4014
|
+
type,
|
|
4015
|
+
isOptional
|
|
4016
|
+
};
|
|
3710
4017
|
} else {
|
|
3711
|
-
this.skipWhitespace();
|
|
3712
|
-
const desc = this.parseParsedString();
|
|
3713
4018
|
return {
|
|
3714
4019
|
name,
|
|
3715
4020
|
desc: desc?.trim(),
|
|
3716
|
-
type
|
|
4021
|
+
type,
|
|
3717
4022
|
isOptional
|
|
3718
4023
|
};
|
|
3719
4024
|
}
|
|
@@ -3729,14 +4034,17 @@ var SignatureParser = class {
|
|
|
3729
4034
|
"datetime",
|
|
3730
4035
|
"date"
|
|
3731
4036
|
];
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
4037
|
+
const foundType = types.find((type) => this.match(type));
|
|
4038
|
+
if (!foundType) {
|
|
4039
|
+
const currentWord = this.input.slice(this.position).match(/^\w+/)?.[0] || "empty";
|
|
4040
|
+
throw new Error(
|
|
4041
|
+
`Invalid type "${currentWord}". Expected one of: ${types.join(", ")}`
|
|
4042
|
+
);
|
|
3736
4043
|
}
|
|
3737
|
-
|
|
4044
|
+
return foundType;
|
|
3738
4045
|
}
|
|
3739
4046
|
parseParsedIdentifier() {
|
|
4047
|
+
this.skipWhitespace();
|
|
3740
4048
|
const match = /^[a-zA-Z_][a-zA-Z_0-9]*/.exec(
|
|
3741
4049
|
this.input.slice(this.position)
|
|
3742
4050
|
);
|
|
@@ -3744,40 +4052,69 @@ var SignatureParser = class {
|
|
|
3744
4052
|
this.position += match[0].length;
|
|
3745
4053
|
return match[0];
|
|
3746
4054
|
}
|
|
3747
|
-
|
|
4055
|
+
const invalidMatch = /^\S+/.exec(this.input.slice(this.position));
|
|
4056
|
+
const invalidId = invalidMatch ? invalidMatch[0] : "empty";
|
|
4057
|
+
throw new Error(
|
|
4058
|
+
`Invalid identifier "${invalidId}". Identifiers must start with a letter or underscore and contain only letters, numbers, or underscores`
|
|
4059
|
+
);
|
|
3748
4060
|
}
|
|
3749
4061
|
parseParsedString() {
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
if (
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
4062
|
+
const quoteChars = ["'", '"'];
|
|
4063
|
+
for (const quoteChar of quoteChars) {
|
|
4064
|
+
if (this.match(quoteChar)) {
|
|
4065
|
+
let content = "";
|
|
4066
|
+
let escaped = false;
|
|
4067
|
+
let startPos = this.position;
|
|
4068
|
+
while (this.position < this.input.length) {
|
|
4069
|
+
const char = this.input[this.position];
|
|
4070
|
+
this.position++;
|
|
4071
|
+
if (escaped) {
|
|
4072
|
+
content += char;
|
|
4073
|
+
escaped = false;
|
|
4074
|
+
} else if (char === "\\") {
|
|
4075
|
+
escaped = true;
|
|
4076
|
+
} else if (char === quoteChar) {
|
|
4077
|
+
return content;
|
|
4078
|
+
} else {
|
|
4079
|
+
content += char;
|
|
4080
|
+
}
|
|
4081
|
+
}
|
|
4082
|
+
const partialString = this.input.slice(startPos, this.position);
|
|
4083
|
+
throw new Error(
|
|
4084
|
+
`Unterminated string starting at position ${startPos}: "${partialString}..."`
|
|
4085
|
+
);
|
|
4086
|
+
}
|
|
3762
4087
|
}
|
|
3763
4088
|
return void 0;
|
|
3764
4089
|
}
|
|
3765
4090
|
skipWhitespace() {
|
|
3766
|
-
const match = /^[
|
|
4091
|
+
const match = /^[\s\t\r\n]+/.exec(this.input.slice(this.position));
|
|
3767
4092
|
if (match) {
|
|
3768
4093
|
this.position += match[0].length;
|
|
3769
4094
|
}
|
|
3770
4095
|
}
|
|
3771
|
-
match(
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
4096
|
+
match(strOrRegex) {
|
|
4097
|
+
let match;
|
|
4098
|
+
if (typeof strOrRegex === "string") {
|
|
4099
|
+
if (this.input.startsWith(strOrRegex, this.position)) {
|
|
4100
|
+
this.position += strOrRegex.length;
|
|
4101
|
+
return true;
|
|
4102
|
+
}
|
|
4103
|
+
} else {
|
|
4104
|
+
match = strOrRegex.exec(this.input.slice(this.position));
|
|
4105
|
+
if (match) {
|
|
4106
|
+
this.position += match[0].length;
|
|
4107
|
+
return true;
|
|
4108
|
+
}
|
|
3775
4109
|
}
|
|
3776
4110
|
return false;
|
|
3777
4111
|
}
|
|
3778
4112
|
expect(str) {
|
|
3779
4113
|
if (!this.match(str)) {
|
|
3780
|
-
|
|
4114
|
+
const found = this.input.slice(this.position, this.position + 10);
|
|
4115
|
+
throw new Error(
|
|
4116
|
+
`Expected "${str}" but found "${found}..." at position ${this.position}`
|
|
4117
|
+
);
|
|
3781
4118
|
}
|
|
3782
4119
|
}
|
|
3783
4120
|
};
|
|
@@ -5011,7 +5348,7 @@ function validateAndParseFieldValue(field, fieldValue) {
|
|
|
5011
5348
|
if (field.type?.name === "json") {
|
|
5012
5349
|
try {
|
|
5013
5350
|
const text = extractBlock(fieldValue);
|
|
5014
|
-
value =
|
|
5351
|
+
value = JSON.parse(text);
|
|
5015
5352
|
return value;
|
|
5016
5353
|
} catch (e) {
|
|
5017
5354
|
throw new ValidationError({
|
|
@@ -5024,7 +5361,7 @@ function validateAndParseFieldValue(field, fieldValue) {
|
|
|
5024
5361
|
if (field.type?.isArray) {
|
|
5025
5362
|
try {
|
|
5026
5363
|
try {
|
|
5027
|
-
value =
|
|
5364
|
+
value = JSON.parse(fieldValue);
|
|
5028
5365
|
} catch {
|
|
5029
5366
|
value = parseMarkdownList(fieldValue);
|
|
5030
5367
|
}
|
|
@@ -5077,9 +5414,6 @@ var extractBlock = (input) => {
|
|
|
5077
5414
|
return input;
|
|
5078
5415
|
};
|
|
5079
5416
|
|
|
5080
|
-
// dsp/functions.ts
|
|
5081
|
-
var import_json52 = __toESM(require("json5"), 1);
|
|
5082
|
-
|
|
5083
5417
|
// dsp/jsonschema.ts
|
|
5084
5418
|
var validateJSONSchema = (schema) => {
|
|
5085
5419
|
const errors = [];
|
|
@@ -5137,7 +5471,7 @@ var AxFunctionProcessor = class {
|
|
|
5137
5471
|
executeFunction = async (fnSpec, func, options) => {
|
|
5138
5472
|
let args;
|
|
5139
5473
|
if (typeof func.args === "string" && func.args.length > 0) {
|
|
5140
|
-
args =
|
|
5474
|
+
args = JSON.parse(func.args);
|
|
5141
5475
|
} else {
|
|
5142
5476
|
args = func.args;
|
|
5143
5477
|
}
|
|
@@ -5424,37 +5758,35 @@ var AxGen = class extends AxProgramWithSignature {
|
|
|
5424
5758
|
functions
|
|
5425
5759
|
}) {
|
|
5426
5760
|
const values = {};
|
|
5427
|
-
const result
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5761
|
+
for (const result of res.results ?? []) {
|
|
5762
|
+
if (res.modelUsage) {
|
|
5763
|
+
this.usage.push({ ...usageInfo, ...res.modelUsage });
|
|
5764
|
+
}
|
|
5765
|
+
mem.addResult(result, sessionId);
|
|
5766
|
+
if (result.content) {
|
|
5767
|
+
extractValues(this.signature, values, result.content);
|
|
5768
|
+
assertAssertions(this.asserts, values);
|
|
5769
|
+
}
|
|
5770
|
+
if (result.functionCalls) {
|
|
5771
|
+
const funcs = parseFunctionCalls(ai, result.functionCalls, values);
|
|
5772
|
+
if (funcs) {
|
|
5773
|
+
if (!functions) {
|
|
5774
|
+
throw new Error("Functions are not defined");
|
|
5775
|
+
}
|
|
5776
|
+
const fx = await processFunctions(
|
|
5777
|
+
ai,
|
|
5778
|
+
functions,
|
|
5779
|
+
funcs,
|
|
5780
|
+
mem,
|
|
5781
|
+
sessionId,
|
|
5782
|
+
traceId
|
|
5783
|
+
);
|
|
5784
|
+
this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
|
|
5444
5785
|
}
|
|
5445
|
-
const fx = await processFunctions(
|
|
5446
|
-
ai,
|
|
5447
|
-
functions,
|
|
5448
|
-
funcs,
|
|
5449
|
-
mem,
|
|
5450
|
-
sessionId,
|
|
5451
|
-
traceId
|
|
5452
|
-
);
|
|
5453
|
-
this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
|
|
5454
5786
|
}
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5787
|
+
if (result.finishReason === "length") {
|
|
5788
|
+
throw new Error("Max tokens reached before completion");
|
|
5789
|
+
}
|
|
5458
5790
|
}
|
|
5459
5791
|
return { ...values };
|
|
5460
5792
|
}
|
|
@@ -5834,6 +6166,25 @@ var AxBalancer = class _AxBalancer {
|
|
|
5834
6166
|
try {
|
|
5835
6167
|
return await this.currentService.chat(req, options);
|
|
5836
6168
|
} catch (e) {
|
|
6169
|
+
if (!(e instanceof AxAIServiceError)) {
|
|
6170
|
+
throw e;
|
|
6171
|
+
}
|
|
6172
|
+
switch (e.constructor) {
|
|
6173
|
+
case AxAIServiceAuthenticationError:
|
|
6174
|
+
throw e;
|
|
6175
|
+
case AxAIServiceStatusError:
|
|
6176
|
+
break;
|
|
6177
|
+
case AxAIServiceNetworkError:
|
|
6178
|
+
break;
|
|
6179
|
+
case AxAIServiceResponseError:
|
|
6180
|
+
break;
|
|
6181
|
+
case AxAIServiceStreamTerminatedError:
|
|
6182
|
+
break;
|
|
6183
|
+
case AxAIServiceTimeoutError:
|
|
6184
|
+
break;
|
|
6185
|
+
default:
|
|
6186
|
+
throw e;
|
|
6187
|
+
}
|
|
5837
6188
|
console.warn(`Service ${this.currentService.getName()} failed`);
|
|
5838
6189
|
if (!this.getNextService()) {
|
|
5839
6190
|
throw e;
|
|
@@ -7520,6 +7871,13 @@ var AxRAG = class extends AxChainOfThought {
|
|
|
7520
7871
|
AxAIOpenAIModel,
|
|
7521
7872
|
AxAIReka,
|
|
7522
7873
|
AxAIRekaModel,
|
|
7874
|
+
AxAIServiceAuthenticationError,
|
|
7875
|
+
AxAIServiceError,
|
|
7876
|
+
AxAIServiceNetworkError,
|
|
7877
|
+
AxAIServiceResponseError,
|
|
7878
|
+
AxAIServiceStatusError,
|
|
7879
|
+
AxAIServiceStreamTerminatedError,
|
|
7880
|
+
AxAIServiceTimeoutError,
|
|
7523
7881
|
AxAITogether,
|
|
7524
7882
|
AxAgent,
|
|
7525
7883
|
AxApacheTika,
|