@ax-llm/ax 10.0.38 → 10.0.40

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.js CHANGED
@@ -525,9 +525,11 @@ var AxBaseAI = class {
525
525
  }
526
526
  },
527
527
  async (span) => {
528
- const res = await this._chat2(model, modelConfig, req, options, span);
529
- span.end();
530
- return res;
528
+ try {
529
+ return await this._chat2(model, modelConfig, req, options, span);
530
+ } finally {
531
+ span.end();
532
+ }
531
533
  }
532
534
  );
533
535
  }
@@ -556,7 +558,7 @@ var AxBaseAI = class {
556
558
  {
557
559
  name: apiConfig.name,
558
560
  url: this.apiURL,
559
- headers: this.buildHeaders(apiConfig.headers),
561
+ headers: await this.buildHeaders(apiConfig.headers),
560
562
  stream: modelConfig.stream,
561
563
  debug: this.debug,
562
564
  fetch: this.fetch,
@@ -650,9 +652,11 @@ var AxBaseAI = class {
650
652
  }
651
653
  },
652
654
  async (span) => {
653
- const res = await this._embed2(embedModel, req, options, span);
654
- span.end();
655
- return res;
655
+ try {
656
+ return await this._embed2(embedModel, req, options, span);
657
+ } finally {
658
+ span.end();
659
+ }
656
660
  }
657
661
  );
658
662
  }
@@ -675,7 +679,7 @@ var AxBaseAI = class {
675
679
  {
676
680
  name: apiConfig.name,
677
681
  url: this.apiURL,
678
- headers: this.buildHeaders(apiConfig.headers),
682
+ headers: await this.buildHeaders(apiConfig.headers),
679
683
  debug: this.debug,
680
684
  fetch: this.fetch,
681
685
  span
@@ -699,8 +703,8 @@ var AxBaseAI = class {
699
703
  span?.end();
700
704
  return res;
701
705
  }
702
- buildHeaders(headers = {}) {
703
- return { ...headers, ...this.headers };
706
+ async buildHeaders(headers = {}) {
707
+ return { ...headers, ...await this.headers() };
704
708
  }
705
709
  };
706
710
  var logChatRequest = (req) => {
@@ -720,7 +724,7 @@ ${colorLog.whiteBright(msg.content)}`;
720
724
  const items2 = msg.content.map((v) => {
721
725
  switch (v.type) {
722
726
  case "text":
723
- return `(Text) ${colorLog.whiteBright(v.text)}`;
727
+ return `${colorLog.whiteBright(v.text)}`;
724
728
  case "image":
725
729
  return `(Image, ${v.mimeType}) ${colorLog.whiteBright(v.image.substring(0, 10))}`;
726
730
  default:
@@ -875,6 +879,30 @@ var AxAIAnthropicImpl = class {
875
879
  const apiConfig = {
876
880
  name: "/messages"
877
881
  };
882
+ let toolsChoice;
883
+ if (req.functionCall && req.functions && req.functions.length > 0) {
884
+ if (typeof req.functionCall === "string") {
885
+ switch (req.functionCall) {
886
+ case "auto":
887
+ toolsChoice = { tool_choice: { type: "auto" } };
888
+ break;
889
+ case "required":
890
+ toolsChoice = { tool_choice: { type: "any" } };
891
+ break;
892
+ case "none":
893
+ throw new Error("functionCall none not supported");
894
+ }
895
+ } else if ("function" in req.functionCall) {
896
+ toolsChoice = {
897
+ tool_choice: {
898
+ type: "tool",
899
+ name: req.functionCall.function.name
900
+ }
901
+ };
902
+ } else {
903
+ throw new Error("Invalid function call type, must be string or object");
904
+ }
905
+ }
878
906
  const system = req.chatPrompt.filter((msg) => msg.role === "system").map((msg) => ({
879
907
  type: "text",
880
908
  text: msg.content,
@@ -897,7 +925,8 @@ var AxAIAnthropicImpl = class {
897
925
  temperature: req.modelConfig?.temperature ?? this.config.temperature,
898
926
  top_p: req.modelConfig?.topP ?? this.config.topP,
899
927
  top_k: req.modelConfig?.topK ?? this.config.topK,
900
- ...tools && tools.length > 0 ? { tools, tool_choice: { type: "auto" } } : {},
928
+ ...toolsChoice,
929
+ ...tools && tools.length > 0 ? { tools } : {},
901
930
  ...stream ? { stream: true } : {},
902
931
  ...system ? { system } : {},
903
932
  messages
@@ -1060,11 +1089,11 @@ var AxAIAnthropic = class extends AxBaseAI {
1060
1089
  super(aiImpl, {
1061
1090
  name: "Anthropic",
1062
1091
  apiURL: "https://api.anthropic.com/v1",
1063
- headers: {
1092
+ headers: async () => ({
1064
1093
  "anthropic-version": "2023-06-01",
1065
1094
  "anthropic-beta": "prompt-caching-2024-07-31",
1066
1095
  "x-api-key": apiKey
1067
- },
1096
+ }),
1068
1097
  modelInfo: axModelInfoAnthropic,
1069
1098
  models: { model: _config.model },
1070
1099
  options,
@@ -1569,7 +1598,7 @@ var AxAIOpenAI = class extends AxBaseAI {
1569
1598
  super(aiImpl, {
1570
1599
  name: "OpenAI",
1571
1600
  apiURL: apiURL ? apiURL : "https://api.openai.com/v1",
1572
- headers: { Authorization: `Bearer ${apiKey}` },
1601
+ headers: async () => ({ Authorization: `Bearer ${apiKey}` }),
1573
1602
  modelInfo,
1574
1603
  models: {
1575
1604
  model: _config.model,
@@ -1621,7 +1650,7 @@ var AxAIAzureOpenAI = class extends AxAIOpenAI {
1621
1650
  host
1622
1651
  ).href
1623
1652
  );
1624
- super.setHeaders({ "api-key": apiKey });
1653
+ super.setHeaders(async () => ({ "api-key": apiKey }));
1625
1654
  }
1626
1655
  };
1627
1656
 
@@ -1881,7 +1910,7 @@ var AxAICohere = class extends AxBaseAI {
1881
1910
  super(aiImpl, {
1882
1911
  name: "Cohere",
1883
1912
  apiURL: "https://api.cohere.ai/v1",
1884
- headers: { Authorization: `Bearer ${apiKey}` },
1913
+ headers: async () => ({ Authorization: `Bearer ${apiKey}` }),
1885
1914
  modelInfo: axModelInfoCohere,
1886
1915
  models: { model: _config.model },
1887
1916
  supportFor: { functions: true, streaming: true },
@@ -2001,6 +2030,61 @@ var AxAIDeepSeek = class extends AxAIOpenAI {
2001
2030
  }
2002
2031
  };
2003
2032
 
2033
+ // ai/google-gemini/auth.ts
2034
+ import { GoogleAuth } from "google-auth-library";
2035
+ var GoogleVertexAuth = class {
2036
+ auth;
2037
+ client;
2038
+ currentToken;
2039
+ tokenExpiry;
2040
+ constructor(config = {}) {
2041
+ this.auth = new GoogleAuth({
2042
+ scopes: ["https://www.googleapis.com/auth/cloud-platform"],
2043
+ ...config
2044
+ });
2045
+ }
2046
+ async getAuthenticatedClient() {
2047
+ if (!this.client) {
2048
+ this.client = await this.auth.getClient();
2049
+ }
2050
+ return this.client;
2051
+ }
2052
+ async getAccessToken() {
2053
+ if (this.currentToken && this.tokenExpiry && Date.now() < this.tokenExpiry) {
2054
+ return this.currentToken;
2055
+ }
2056
+ const client = await this.getAuthenticatedClient();
2057
+ const tokenResponse = await client.getAccessToken();
2058
+ this.currentToken = tokenResponse.token ?? void 0;
2059
+ const expiry = this.getExpiry(tokenResponse);
2060
+ const fiveMinutes = 5 * 60 * 1e3;
2061
+ this.tokenExpiry = expiry - fiveMinutes;
2062
+ return this.currentToken;
2063
+ }
2064
+ /**
2065
+ * Get the expiry date from the token response.
2066
+ */
2067
+ getExpiry(tokenResponse) {
2068
+ const oneHour = 3600 * 1e3;
2069
+ let expiry = Date.now() + oneHour;
2070
+ let responseExpiry = tokenResponse.res?.data?.expiry_date;
2071
+ if (responseExpiry) {
2072
+ if (typeof responseExpiry === "number") {
2073
+ expiry = responseExpiry;
2074
+ } else if (responseExpiry instanceof Date) {
2075
+ expiry = responseExpiry.getTime();
2076
+ } else if (typeof responseExpiry === "string") {
2077
+ expiry = new Date(responseExpiry).getTime();
2078
+ } else {
2079
+ console.warn("Unknown expiry type", responseExpiry);
2080
+ }
2081
+ } else {
2082
+ console.warn("No expiry date found in response", tokenResponse.res?.data);
2083
+ }
2084
+ return expiry;
2085
+ }
2086
+ };
2087
+
2004
2088
  // ai/google-gemini/types.ts
2005
2089
  var AxAIGoogleGeminiModel = /* @__PURE__ */ ((AxAIGoogleGeminiModel2) => {
2006
2090
  AxAIGoogleGeminiModel2["Gemini1Pro"] = "gemini-1.0-pro";
@@ -2013,6 +2097,7 @@ var AxAIGoogleGeminiModel = /* @__PURE__ */ ((AxAIGoogleGeminiModel2) => {
2013
2097
  })(AxAIGoogleGeminiModel || {});
2014
2098
  var AxAIGoogleGeminiEmbedModel = /* @__PURE__ */ ((AxAIGoogleGeminiEmbedModel2) => {
2015
2099
  AxAIGoogleGeminiEmbedModel2["TextEmbedding004"] = "text-embedding-004";
2100
+ AxAIGoogleGeminiEmbedModel2["TextEmbedding005"] = "text-embedding-005";
2016
2101
  return AxAIGoogleGeminiEmbedModel2;
2017
2102
  })(AxAIGoogleGeminiEmbedModel || {});
2018
2103
  var AxAIGoogleGeminiSafetyCategory = /* @__PURE__ */ ((AxAIGoogleGeminiSafetyCategory2) => {
@@ -2089,10 +2174,11 @@ var axAIGoogleGeminiDefaultConfig = () => structuredClone({
2089
2174
  ...axBaseAIDefaultConfig()
2090
2175
  });
2091
2176
  var AxAIGoogleGeminiImpl = class {
2092
- constructor(config, apiKey, isVertex, options) {
2177
+ constructor(config, isVertex, apiKey, keyFile, options) {
2093
2178
  this.config = config;
2094
- this.apiKey = apiKey;
2095
2179
  this.isVertex = isVertex;
2180
+ this.apiKey = apiKey;
2181
+ this.keyFile = keyFile;
2096
2182
  this.options = options;
2097
2183
  }
2098
2184
  getModelConfig() {
@@ -2119,7 +2205,7 @@ var AxAIGoogleGeminiImpl = class {
2119
2205
  const apiConfig = {
2120
2206
  name: stream ? `/models/${model}:streamGenerateContent?alt=sse` : `/models/${model}:generateContent`
2121
2207
  };
2122
- if (this.isVertex === false) {
2208
+ if (!this.isVertex) {
2123
2209
  const pf = stream ? "&" : "?";
2124
2210
  apiConfig.name += `${pf}key=${this.apiKey}`;
2125
2211
  }
@@ -2266,15 +2352,28 @@ var AxAIGoogleGeminiImpl = class {
2266
2352
  if (!req.texts || req.texts.length === 0) {
2267
2353
  throw new Error("Embed texts is empty");
2268
2354
  }
2269
- const apiConfig = {
2270
- name: `/models/${model}:batchEmbedContents?key=${this.apiKey}`
2271
- };
2272
- const reqValue = {
2273
- requests: req.texts.map((text) => ({
2274
- model: "models/" + model,
2275
- content: { parts: [{ text }] }
2276
- }))
2277
- };
2355
+ let apiConfig;
2356
+ let reqValue;
2357
+ if (this.isVertex) {
2358
+ apiConfig = {
2359
+ name: `/models/${model}:predict`
2360
+ };
2361
+ reqValue = {
2362
+ instances: req.texts.map((text) => ({
2363
+ content: text
2364
+ }))
2365
+ };
2366
+ } else {
2367
+ apiConfig = {
2368
+ name: `/models/${model}:batchEmbedContents?key=${this.apiKey}`
2369
+ };
2370
+ reqValue = {
2371
+ requests: req.texts.map((text) => ({
2372
+ model: "models/" + model,
2373
+ content: { parts: [{ text }] }
2374
+ }))
2375
+ };
2376
+ }
2278
2377
  return [apiConfig, reqValue];
2279
2378
  };
2280
2379
  createChatResp = (resp) => {
@@ -2336,7 +2435,16 @@ var AxAIGoogleGeminiImpl = class {
2336
2435
  return this.createChatResp(resp);
2337
2436
  };
2338
2437
  createEmbedResp = (resp) => {
2339
- const embeddings = resp.embeddings.map((embedding) => embedding.values);
2438
+ let embeddings;
2439
+ if (this.isVertex) {
2440
+ embeddings = resp.predictions.map(
2441
+ (prediction) => prediction.embeddings.values
2442
+ );
2443
+ } else {
2444
+ embeddings = resp.embeddings.map(
2445
+ (embedding) => embedding.values
2446
+ );
2447
+ }
2340
2448
  return {
2341
2449
  embeddings
2342
2450
  };
@@ -2347,28 +2455,44 @@ var AxAIGoogleGemini = class extends AxBaseAI {
2347
2455
  apiKey,
2348
2456
  projectId,
2349
2457
  region,
2458
+ keyFile,
2350
2459
  config,
2351
2460
  options,
2352
2461
  modelMap
2353
2462
  }) {
2354
- if (!apiKey || apiKey === "") {
2355
- throw new Error("GoogleGemini AI API key not set");
2356
- }
2357
2463
  const isVertex = projectId !== void 0 && region !== void 0;
2358
2464
  let apiURL;
2359
2465
  let headers;
2360
2466
  if (isVertex) {
2361
2467
  apiURL = `https://${region}-aiplatform.googleapis.com/v1/projects/${projectId}/locations/${region}/publishers/google/`;
2362
- headers = { Authorization: `Bearer ${apiKey}` };
2468
+ if (apiKey) {
2469
+ headers = async () => ({ Authorization: `Bearer ${apiKey}` });
2470
+ } else {
2471
+ const vertexAuth = new GoogleVertexAuth({
2472
+ keyFile
2473
+ });
2474
+ headers = async () => ({
2475
+ Authorization: `Bearer ${await vertexAuth.getAccessToken()}`
2476
+ });
2477
+ }
2363
2478
  } else {
2479
+ if (!apiKey) {
2480
+ throw new Error("GoogleGemini AI API key not set");
2481
+ }
2364
2482
  apiURL = "https://generativelanguage.googleapis.com/v1beta";
2365
- headers = {};
2483
+ headers = async () => ({});
2366
2484
  }
2367
2485
  const _config = {
2368
2486
  ...axAIGoogleGeminiDefaultConfig(),
2369
2487
  ...config
2370
2488
  };
2371
- const aiImpl = new AxAIGoogleGeminiImpl(_config, apiKey, isVertex, options);
2489
+ const aiImpl = new AxAIGoogleGeminiImpl(
2490
+ _config,
2491
+ isVertex,
2492
+ apiKey,
2493
+ keyFile,
2494
+ options
2495
+ );
2372
2496
  super(aiImpl, {
2373
2497
  name: "GoogleGeminiAI",
2374
2498
  apiURL,
@@ -2638,7 +2762,7 @@ var AxAIHuggingFace = class extends AxBaseAI {
2638
2762
  super(aiImpl, {
2639
2763
  name: "HuggingFace",
2640
2764
  apiURL: "https://api-inference.huggingface.co",
2641
- headers: { Authorization: `Bearer ${apiKey}` },
2765
+ headers: async () => ({ Authorization: `Bearer ${apiKey}` }),
2642
2766
  modelInfo: axModelInfoHuggingFace,
2643
2767
  models: { model: _config.model },
2644
2768
  options,
@@ -2987,7 +3111,7 @@ var AxAIReka = class extends AxBaseAI {
2987
3111
  super(aiImpl, {
2988
3112
  name: "Reka",
2989
3113
  apiURL: apiURL ? apiURL : "https://api.reka.ai/v1/chat",
2990
- headers: { "X-Api-Key": apiKey },
3114
+ headers: async () => ({ "X-Api-Key": apiKey }),
2991
3115
  modelInfo,
2992
3116
  models: {
2993
3117
  model: _config.model
@@ -3111,9 +3235,6 @@ var AxAI = class {
3111
3235
  }
3112
3236
  };
3113
3237
 
3114
- // prompts/agent.ts
3115
- import { SpanKind as SpanKind3 } from "@opentelemetry/api";
3116
-
3117
3238
  // dsp/generate.ts
3118
3239
  import { ReadableStream } from "stream/web";
3119
3240
  import { SpanKind as SpanKind2 } from "@opentelemetry/api";
@@ -3302,7 +3423,7 @@ var AxAssertionError = class extends Error {
3302
3423
  extraFields.push({
3303
3424
  name: "error",
3304
3425
  title: "Error In Output",
3305
- description: this.message
3426
+ description: `You must follow the following instructions, "${this.message}".`
3306
3427
  });
3307
3428
  return extraFields;
3308
3429
  };
@@ -3341,18 +3462,6 @@ var assertStreamingAssertions = (asserts, values, xstate, content, final) => {
3341
3462
  }
3342
3463
  }
3343
3464
  };
3344
- var assertRequiredFields = (sig, values) => {
3345
- const fields = sig.getOutputFields();
3346
- const missingFields = fields.filter(
3347
- (f) => !f.isOptional && !(f.name in values)
3348
- );
3349
- if (missingFields.length > 0) {
3350
- throw new AxAssertionError({
3351
- message: `Output must include: ${missingFields.map((f) => `\`${f.title}:\``).join(", ")}`,
3352
- values
3353
- });
3354
- }
3355
- };
3356
3465
 
3357
3466
  // dsp/extract.ts
3358
3467
  import JSON5 from "json5";
@@ -3900,6 +4009,21 @@ var parseMarkdownList = (input) => {
3900
4009
  }
3901
4010
  return list;
3902
4011
  };
4012
+ function mergeDeltas(base, delta) {
4013
+ const merged = { ...base };
4014
+ for (const key in delta) {
4015
+ const baseValue = base[key];
4016
+ const deltaValue = delta[key];
4017
+ if (Array.isArray(baseValue) && Array.isArray(deltaValue)) {
4018
+ merged[key] = [...baseValue, ...deltaValue];
4019
+ } else if (typeof baseValue === "string" && typeof deltaValue === "string") {
4020
+ merged[key] = baseValue + deltaValue;
4021
+ } else {
4022
+ merged[key] = deltaValue;
4023
+ }
4024
+ }
4025
+ return merged;
4026
+ }
3903
4027
 
3904
4028
  // dsp/program.ts
3905
4029
  var AxProgramWithSignature = class {
@@ -3932,6 +4056,9 @@ var AxProgramWithSignature = class {
3932
4056
  async forward(_ai, _values, _options) {
3933
4057
  throw new Error("forward() not implemented");
3934
4058
  }
4059
+ async *streamingForward(_ai, _values, _options) {
4060
+ throw new Error("streamingForward() not implemented");
4061
+ }
3935
4062
  setId(id) {
3936
4063
  this.key = { id, custom: true };
3937
4064
  for (const child of this.children) {
@@ -4026,6 +4153,9 @@ var AxProgram = class {
4026
4153
  async forward(_ai, _values, _options) {
4027
4154
  throw new Error("forward() not implemented");
4028
4155
  }
4156
+ async *streamingForward(_ai, _values, _options) {
4157
+ throw new Error("streamingForward() not implemented");
4158
+ }
4029
4159
  setId(id) {
4030
4160
  this.key = { id, custom: true };
4031
4161
  for (const child of this.children) {
@@ -4123,9 +4253,10 @@ ${outputFields}`);
4123
4253
  task.push(formattingRules.trim());
4124
4254
  const desc = this.sig.getDescription();
4125
4255
  if (desc) {
4256
+ const capitalized = capitalizeFirstLetter(desc.trim());
4126
4257
  task.push(
4127
4258
  `## TASK DESCRIPTION
4128
- ${capitalizeFirstLetter(desc.endsWith(".") ? desc : desc + ".")}`
4259
+ ${capitalized.endsWith(".") ? capitalized : capitalized + "."}`
4129
4260
  );
4130
4261
  }
4131
4262
  this.task = {
@@ -4173,16 +4304,42 @@ ${capitalizeFirstLetter(desc.endsWith(".") ? desc : desc + ".")}`
4173
4304
  };
4174
4305
  renderExtraFields = (extraFields) => {
4175
4306
  const prompt = [];
4176
- if (extraFields && extraFields.length > 0) {
4177
- extraFields.forEach((field) => {
4178
- const fn = this.fieldTemplates?.[field.name] ?? this.defaultRenderInField;
4179
- prompt.push(...fn(field, field.description));
4180
- });
4181
- }
4182
- if (prompt.every((v) => v.type === "text")) {
4183
- return prompt.map((v) => v.text).join("\n\n");
4184
- }
4185
- return prompt.reduce(combineConsecutiveStrings("\n"), []);
4307
+ if (!extraFields || extraFields.length === 0) {
4308
+ return prompt;
4309
+ }
4310
+ const groupedFields = extraFields.reduce(
4311
+ (acc, field) => {
4312
+ const title = field.title;
4313
+ if (!acc[title]) {
4314
+ acc[title] = [];
4315
+ }
4316
+ acc[title].push(field);
4317
+ return acc;
4318
+ },
4319
+ {}
4320
+ );
4321
+ const formattedGroupedFields = Object.entries(groupedFields).map(([title, fields]) => {
4322
+ if (fields.length === 1) {
4323
+ const field = fields[0];
4324
+ return {
4325
+ title,
4326
+ name: field.name,
4327
+ description: field.description
4328
+ };
4329
+ } else if (fields.length > 1) {
4330
+ const valuesList = fields.map((field) => `- ${field.description}`).join("\n");
4331
+ return {
4332
+ title,
4333
+ name: fields[0].name,
4334
+ description: valuesList
4335
+ };
4336
+ }
4337
+ }).filter(Boolean);
4338
+ formattedGroupedFields.forEach((field) => {
4339
+ const fn = this.fieldTemplates?.[field.name] ?? this.defaultRenderInField;
4340
+ prompt.push(...fn(field, field.description));
4341
+ });
4342
+ return prompt;
4186
4343
  };
4187
4344
  renderExamples = (data) => {
4188
4345
  const list = [];
@@ -4431,34 +4588,47 @@ function capitalizeFirstLetter(str) {
4431
4588
  }
4432
4589
 
4433
4590
  // dsp/validate.ts
4591
+ var colorLog4 = new ColorLog();
4434
4592
  var ValidationError = class extends Error {
4435
- field;
4436
- value;
4593
+ fields;
4437
4594
  constructor({
4438
4595
  message,
4439
- field,
4440
- value
4596
+ fields
4441
4597
  }) {
4442
4598
  super(message);
4443
- this.field = field;
4444
- this.value = value;
4599
+ this.fields = fields;
4445
4600
  this.name = this.constructor.name;
4446
4601
  Error.captureStackTrace(this, this.constructor);
4447
4602
  }
4448
- getField = () => this.field;
4449
- getValue = () => this.value;
4603
+ getFields = () => this.fields;
4450
4604
  getFixingInstructions = () => {
4451
- const f = this.field;
4452
- const extraFields = [
4453
- {
4454
- name: `outputError`,
4455
- title: `Invalid Output Field`,
4456
- description: `Invalid format for field \`${f.title}\` of type \`${toFieldType(f.type)}\`, format should match: \`${f.description}\``
4457
- }
4458
- ];
4459
- return extraFields;
4605
+ return this.fields.map((field) => ({
4606
+ name: "outputError",
4607
+ title: "Error In Output",
4608
+ description: `Please fix and return the field \`${field.title}\` of type \`${toFieldType(field.type)}\`, ${this.message}.`
4609
+ }));
4460
4610
  };
4461
4611
  };
4612
+ function handleValidationError(mem, errorFields, ai, promptTemplate, sessionId) {
4613
+ mem.add(
4614
+ {
4615
+ role: "user",
4616
+ content: promptTemplate.renderExtraFields(errorFields)
4617
+ },
4618
+ sessionId
4619
+ );
4620
+ mem.addTag("error");
4621
+ if (ai.getOptions().debug) {
4622
+ process.stdout.write(
4623
+ colorLog4.red(
4624
+ `
4625
+ Error Correction:
4626
+ ${JSON.stringify(errorFields, null, 2)}
4627
+ `
4628
+ )
4629
+ );
4630
+ }
4631
+ }
4462
4632
 
4463
4633
  // dsp/datetime.ts
4464
4634
  function parseLLMFriendlyDate(field, dateStr) {
@@ -4466,7 +4636,7 @@ function parseLLMFriendlyDate(field, dateStr) {
4466
4636
  return _parseLLMFriendlyDate(dateStr);
4467
4637
  } catch (err) {
4468
4638
  const message = err.message;
4469
- throw new ValidationError({ field, message, value: dateStr });
4639
+ throw new ValidationError({ fields: [field], message, value: dateStr });
4470
4640
  }
4471
4641
  }
4472
4642
  function _parseLLMFriendlyDate(dateStr) {
@@ -4483,7 +4653,7 @@ function parseLLMFriendlyDateTime(field, dateStr) {
4483
4653
  return _parseLLMFriendlyDateTime(dateStr);
4484
4654
  } catch (err) {
4485
4655
  const message = err.message;
4486
- throw new ValidationError({ field, message, value: dateStr });
4656
+ throw new ValidationError({ fields: [field], message, value: dateStr });
4487
4657
  }
4488
4658
  }
4489
4659
  function _parseLLMFriendlyDateTime(dateTimeStr) {
@@ -4525,41 +4695,61 @@ var formatDateWithTimezone = (date) => {
4525
4695
 
4526
4696
  // dsp/extract.ts
4527
4697
  var extractValues = (sig, values, content) => {
4528
- const xstate = { s: -1 };
4698
+ const xstate = { extractedFields: [], s: -1 };
4529
4699
  streamingExtractValues(sig, values, xstate, content);
4530
- streamingExtractFinalValue(values, xstate, content);
4700
+ streamingExtractFinalValue(sig, values, xstate, content);
4701
+ };
4702
+ var checkMissingRequiredFields = (xstate, values, currentIndex) => {
4703
+ const missingFields = [];
4704
+ for (let i = 0; i < currentIndex; i++) {
4705
+ const field = xstate.extractedFields[i];
4706
+ if (field && !field.isOptional && values[field.name] === void 0) {
4707
+ missingFields.push(field);
4708
+ }
4709
+ }
4710
+ if (missingFields.length > 0) {
4711
+ throw new ValidationError({
4712
+ message: `Required ${missingFields.length === 1 ? "field" : "fields"} not found`,
4713
+ fields: missingFields
4714
+ });
4715
+ }
4531
4716
  };
4532
- var streamingExtractValues = (sig, values, state, content) => {
4717
+ var streamingExtractValues = (sig, values, xstate, content) => {
4533
4718
  const fields = sig.getOutputFields();
4534
- for (const field of fields) {
4719
+ for (const [index, field] of fields.entries()) {
4535
4720
  if (field.name in values) {
4536
4721
  continue;
4537
4722
  }
4538
4723
  const prefix = field.title + ":";
4539
- const e = content.indexOf(prefix, state.s + 1);
4724
+ const e = content.indexOf(prefix, xstate.s + 1);
4540
4725
  if (e === -1) {
4541
4726
  continue;
4542
4727
  }
4543
- if (state.currField) {
4544
- const val = content.substring(state.s, e).trim().replace(/---+$/, "").trim();
4545
- values[state.currField.name] = validateAndParseFieldValue(
4546
- state.currField,
4547
- val
4548
- );
4728
+ if (xstate.currField) {
4729
+ const val = content.substring(xstate.s, e);
4730
+ const parsedValue = validateAndParseFieldValue(xstate.currField, val);
4731
+ if (parsedValue !== void 0) {
4732
+ values[xstate.currField.name] = parsedValue;
4733
+ }
4734
+ }
4735
+ checkMissingRequiredFields(xstate, values, index);
4736
+ xstate.s = e + prefix.length;
4737
+ xstate.currField = field;
4738
+ if (!xstate.extractedFields.includes(field)) {
4739
+ xstate.extractedFields.push(field);
4549
4740
  }
4550
- state.s = e + prefix.length;
4551
- state.currField = field;
4552
4741
  }
4553
4742
  };
4554
- var streamingExtractFinalValue = (values, state, content) => {
4555
- if (!state.currField) {
4556
- return;
4743
+ var streamingExtractFinalValue = (sig, values, xstate, content) => {
4744
+ if (xstate.currField) {
4745
+ const val = content.substring(xstate.s);
4746
+ const parsedValue = validateAndParseFieldValue(xstate.currField, val);
4747
+ if (parsedValue !== void 0) {
4748
+ values[xstate.currField.name] = parsedValue;
4749
+ }
4557
4750
  }
4558
- const val = content.substring(state.s).trim().replace(/---+$/, "").trim();
4559
- values[state.currField.name] = validateAndParseFieldValue(
4560
- state.currField,
4561
- val
4562
- );
4751
+ const fields = sig.getOutputFields();
4752
+ checkMissingRequiredFields(xstate, values, fields.length - 1);
4563
4753
  };
4564
4754
  var convertValueToType = (field, val) => {
4565
4755
  switch (field.type?.name) {
@@ -4597,59 +4787,98 @@ var convertValueToType = (field, val) => {
4597
4787
  return val;
4598
4788
  }
4599
4789
  };
4600
- var expectedTypeError = (field, err, value = "") => {
4601
- const exp = field.type?.isArray ? `array of ${field.type.name}` : field.type?.name;
4602
- const message = `Error '${err.message}', expected '${exp}' got '${value}'`;
4603
- return new ValidationError({ message, field, value });
4604
- };
4790
+ function* streamingValues(sig, values, xstate, content) {
4791
+ if (!xstate.currField) {
4792
+ return;
4793
+ }
4794
+ const fieldName = xstate.currField.name;
4795
+ if (!xstate.streamedIndex) {
4796
+ xstate.streamedIndex = { [fieldName]: 0 };
4797
+ }
4798
+ if (!xstate.currField.type || !xstate.currField.type.isArray && xstate.currField.type.name === "string") {
4799
+ const s = xstate.s + (xstate.streamedIndex[fieldName] ?? 0);
4800
+ const v = content.substring(s);
4801
+ yield { [fieldName]: v };
4802
+ xstate.streamedIndex[fieldName] = v.length;
4803
+ return;
4804
+ }
4805
+ for (const key of Object.keys(values)) {
4806
+ const value = values[key];
4807
+ if (Array.isArray(value)) {
4808
+ const s = xstate.streamedIndex[fieldName] ?? 0;
4809
+ const v = value.slice(s);
4810
+ if (v) {
4811
+ yield { [fieldName]: v };
4812
+ xstate.streamedIndex[fieldName] = s + 1;
4813
+ }
4814
+ continue;
4815
+ }
4816
+ if (!xstate.streamedIndex[fieldName]) {
4817
+ yield { [fieldName]: value };
4818
+ xstate.streamedIndex[fieldName] = 1;
4819
+ }
4820
+ }
4821
+ }
4605
4822
  function validateAndParseFieldValue(field, fieldValue) {
4606
- const fv = fieldValue?.toLocaleLowerCase();
4607
- if (!fieldValue || !fv || fv === "" || fv === "null" || fv === "undefined") {
4823
+ const fv = fieldValue?.trim();
4824
+ if (!fv || !fv || fv === "" || fv === "null" || fv === "NULL" || fv === "undefined") {
4608
4825
  if (field.isOptional) {
4609
4826
  return;
4610
4827
  }
4611
- throw expectedTypeError(field, new Error("Empty value"), fieldValue);
4828
+ throw new ValidationError({
4829
+ message: "Required field is missing",
4830
+ fields: [field],
4831
+ value: fv
4832
+ });
4612
4833
  }
4613
- let value = fieldValue;
4834
+ let value;
4614
4835
  if (field.type?.name === "json") {
4615
4836
  try {
4616
- const text = extractBlock(fieldValue);
4837
+ const text = extractBlock(fv);
4617
4838
  value = JSON5.parse(text);
4618
4839
  return value;
4619
4840
  } catch (e) {
4620
- throw expectedTypeError(field, e, fieldValue);
4841
+ throw new ValidationError({
4842
+ message: "Invalid JSON: " + e.message,
4843
+ fields: [field],
4844
+ value: fv
4845
+ });
4621
4846
  }
4622
4847
  }
4623
4848
  if (field.type?.isArray) {
4624
4849
  try {
4625
4850
  try {
4626
- value = JSON5.parse(fieldValue);
4851
+ value = JSON5.parse(fv);
4627
4852
  } catch {
4628
- value = parseMarkdownList(fieldValue);
4853
+ value = parseMarkdownList(fv);
4629
4854
  }
4630
4855
  if (!Array.isArray(value)) {
4631
4856
  throw new Error("Expected an array");
4632
4857
  }
4633
4858
  } catch (e) {
4634
- throw expectedTypeError(field, e, fieldValue);
4859
+ throw new ValidationError({
4860
+ message: "Invalid array: " + e.message,
4861
+ fields: [field],
4862
+ value: fv
4863
+ });
4635
4864
  }
4636
4865
  }
4637
- if (Array.isArray(value)) {
4638
- for (const [index, item] of value.entries()) {
4639
- try {
4866
+ try {
4867
+ if (Array.isArray(value)) {
4868
+ for (const [index, item] of value.entries()) {
4640
4869
  value[index] = convertValueToType(field, item);
4641
- } catch (e) {
4642
- throw expectedTypeError(field, e, item);
4643
4870
  }
4871
+ } else {
4872
+ value = convertValueToType(field, fv);
4644
4873
  }
4645
- } else {
4646
- try {
4647
- value = convertValueToType(field, fieldValue);
4648
- } catch (e) {
4649
- throw expectedTypeError(field, e, fieldValue);
4650
- }
4874
+ } catch (e) {
4875
+ throw new ValidationError({
4876
+ message: e.message,
4877
+ fields: [field],
4878
+ value: fieldValue
4879
+ });
4651
4880
  }
4652
- return value;
4881
+ return value ?? fv;
4653
4882
  }
4654
4883
  var extractBlock = (input) => {
4655
4884
  const jsonBlockPattern = /```([A-Za-z]+)?\s*([\s\S]*?)\s*```/g;
@@ -4816,7 +5045,6 @@ function parseFunctionCalls(ai, functionCalls, values, model) {
4816
5045
  }
4817
5046
 
4818
5047
  // dsp/generate.ts
4819
- var colorLog4 = new ColorLog();
4820
5048
  var AxGen = class extends AxProgramWithSignature {
4821
5049
  promptTemplate;
4822
5050
  asserts;
@@ -4881,7 +5109,7 @@ var AxGen = class extends AxProgramWithSignature {
4881
5109
  );
4882
5110
  return res;
4883
5111
  }
4884
- async forwardCore({
5112
+ async *forwardCore({
4885
5113
  ai,
4886
5114
  mem,
4887
5115
  options
@@ -4897,7 +5125,18 @@ var AxGen = class extends AxProgramWithSignature {
4897
5125
  options
4898
5126
  });
4899
5127
  if (res instanceof ReadableStream) {
4900
- return await this.processSteamingResponse({
5128
+ yield* this.processStreamingResponse({
5129
+ ai,
5130
+ model,
5131
+ res,
5132
+ usageInfo,
5133
+ mem,
5134
+ traceId,
5135
+ sessionId,
5136
+ functions
5137
+ });
5138
+ } else {
5139
+ yield await this.processResponse({
4901
5140
  ai,
4902
5141
  model,
4903
5142
  res,
@@ -4908,18 +5147,8 @@ var AxGen = class extends AxProgramWithSignature {
4908
5147
  functions
4909
5148
  });
4910
5149
  }
4911
- return await this.processResponse({
4912
- ai,
4913
- model,
4914
- res,
4915
- usageInfo,
4916
- mem,
4917
- traceId,
4918
- sessionId,
4919
- functions
4920
- });
4921
5150
  }
4922
- async processSteamingResponse({
5151
+ async *processStreamingResponse({
4923
5152
  ai,
4924
5153
  model,
4925
5154
  res,
@@ -4931,36 +5160,39 @@ var AxGen = class extends AxProgramWithSignature {
4931
5160
  }) {
4932
5161
  const functionCalls = [];
4933
5162
  const values = {};
4934
- const xstate = { s: -1 };
5163
+ const xstate = { extractedFields: [], s: -1 };
4935
5164
  let content = "";
4936
5165
  for await (const v of res) {
4937
- for (const result of v.results ?? []) {
4938
- if (v.modelUsage) {
4939
- this.usage.push({ ...usageInfo, ...v.modelUsage });
4940
- }
4941
- if (result.content) {
4942
- content += result.content;
4943
- mem.updateResult({ name: result.name, content }, sessionId);
4944
- assertStreamingAssertions(
4945
- this.streamingAsserts,
4946
- values,
4947
- xstate,
4948
- content,
4949
- false
4950
- );
4951
- streamingExtractValues(this.signature, values, xstate, content);
4952
- assertAssertions(this.asserts, values);
4953
- }
4954
- if (result.functionCalls) {
4955
- mergeFunctionCalls(functionCalls, result.functionCalls);
4956
- mem.updateResult(
4957
- { name: result.name, content, functionCalls },
4958
- sessionId
4959
- );
4960
- }
4961
- if (result.finishReason === "length") {
4962
- throw new Error("Max tokens reached before completion");
4963
- }
5166
+ const result = v.results[0];
5167
+ if (!result) {
5168
+ continue;
5169
+ }
5170
+ if (v.modelUsage) {
5171
+ this.usage.push({ ...usageInfo, ...v.modelUsage });
5172
+ }
5173
+ if (result.content) {
5174
+ content += result.content;
5175
+ mem.updateResult({ name: result.name, content }, sessionId);
5176
+ assertStreamingAssertions(
5177
+ this.streamingAsserts,
5178
+ values,
5179
+ xstate,
5180
+ content,
5181
+ false
5182
+ );
5183
+ streamingExtractValues(this.signature, values, xstate, content);
5184
+ assertAssertions(this.asserts, values);
5185
+ yield* streamingValues(this.signature, values, xstate, content);
5186
+ }
5187
+ if (result.functionCalls) {
5188
+ mergeFunctionCalls(functionCalls, result.functionCalls);
5189
+ mem.updateResult(
5190
+ { name: result.name, content, functionCalls },
5191
+ sessionId
5192
+ );
5193
+ }
5194
+ if (result.finishReason === "length") {
5195
+ throw new Error("Max tokens reached before completion");
4964
5196
  }
4965
5197
  }
4966
5198
  const funcs = parseFunctionCalls(ai, functionCalls, values, model);
@@ -4978,7 +5210,6 @@ var AxGen = class extends AxProgramWithSignature {
4978
5210
  );
4979
5211
  this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
4980
5212
  }
4981
- streamingExtractFinalValue(values, xstate, content);
4982
5213
  assertStreamingAssertions(
4983
5214
  this.streamingAsserts,
4984
5215
  values,
@@ -4986,8 +5217,9 @@ var AxGen = class extends AxProgramWithSignature {
4986
5217
  content,
4987
5218
  true
4988
5219
  );
5220
+ streamingExtractFinalValue(this.signature, values, xstate, content);
4989
5221
  assertAssertions(this.asserts, values);
4990
- return { ...values };
5222
+ return values;
4991
5223
  }
4992
5224
  async processResponse({
4993
5225
  ai,
@@ -4999,45 +5231,47 @@ var AxGen = class extends AxProgramWithSignature {
4999
5231
  functions
5000
5232
  }) {
5001
5233
  const values = {};
5002
- for (const result of res.results ?? []) {
5003
- if (res.modelUsage) {
5004
- this.usage.push({ ...usageInfo, ...res.modelUsage });
5005
- }
5006
- mem.addResult(result, sessionId);
5007
- if (result.content) {
5008
- extractValues(this.signature, values, result.content);
5009
- assertAssertions(this.asserts, values);
5010
- }
5011
- if (result.functionCalls) {
5012
- const funcs = parseFunctionCalls(ai, result.functionCalls, values);
5013
- if (funcs) {
5014
- if (!functions) {
5015
- throw new Error("Functions are not defined");
5016
- }
5017
- const fx = await processFunctions(
5018
- ai,
5019
- functions,
5020
- funcs,
5021
- mem,
5022
- sessionId,
5023
- traceId
5024
- );
5025
- this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
5234
+ const result = res.results[0];
5235
+ if (!result) {
5236
+ throw new Error("No result found");
5237
+ }
5238
+ if (res.modelUsage) {
5239
+ this.usage.push({ ...usageInfo, ...res.modelUsage });
5240
+ }
5241
+ mem.addResult(result, sessionId);
5242
+ if (result.content) {
5243
+ extractValues(this.signature, values, result.content);
5244
+ assertAssertions(this.asserts, values);
5245
+ }
5246
+ if (result.functionCalls) {
5247
+ const funcs = parseFunctionCalls(ai, result.functionCalls, values);
5248
+ if (funcs) {
5249
+ if (!functions) {
5250
+ throw new Error("Functions are not defined");
5026
5251
  }
5027
- }
5028
- if (result.finishReason === "length") {
5029
- throw new Error("Max tokens reached before completion");
5252
+ const fx = await processFunctions(
5253
+ ai,
5254
+ functions,
5255
+ funcs,
5256
+ mem,
5257
+ sessionId,
5258
+ traceId
5259
+ );
5260
+ this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
5030
5261
  }
5031
5262
  }
5263
+ if (result.finishReason === "length") {
5264
+ throw new Error("Max tokens reached before completion");
5265
+ }
5032
5266
  return { ...values };
5033
5267
  }
5034
- async _forward(ai, values, options, span) {
5268
+ async *_forward2(ai, values, options, span) {
5035
5269
  const stopFunction = (options?.stopFunction ?? this.options?.stopFunction)?.toLowerCase();
5036
- const maxRetries = options?.maxRetries ?? this.options?.maxRetries ?? 3;
5037
- const maxSteps = options?.maxSteps ?? this.options?.maxSteps ?? 10;
5038
- const mem = options?.mem ?? this.options?.mem ?? new AxMemory();
5270
+ const maxRetries = options.maxRetries ?? this.options?.maxRetries ?? 10;
5271
+ const maxSteps = options.maxSteps ?? this.options?.maxSteps ?? 10;
5272
+ const mem = options.mem ?? this.options?.mem ?? new AxMemory();
5039
5273
  let err;
5040
- if (options?.functions && options?.functions.length > 0) {
5274
+ if (options?.functions && options.functions.length > 0) {
5041
5275
  const promptTemplate = this.options?.promptTemplate ?? AxPromptTemplate;
5042
5276
  this.promptTemplate = new promptTemplate(
5043
5277
  this.signature,
@@ -5052,25 +5286,22 @@ var AxGen = class extends AxProgramWithSignature {
5052
5286
  multiStepLoop: for (let n = 0; n < maxSteps; n++) {
5053
5287
  for (let errCount = 0; errCount < maxRetries; errCount++) {
5054
5288
  try {
5055
- const output = await this.forwardCore({
5056
- options,
5057
- ai,
5058
- mem
5059
- });
5289
+ const generator = this.forwardCore({ options, ai, mem });
5290
+ for await (const delta of generator) {
5291
+ yield {
5292
+ version: errCount,
5293
+ delta
5294
+ };
5295
+ }
5060
5296
  const lastMemItem = mem.getLast(options?.sessionId);
5061
- if (lastMemItem) {
5062
- const stopFunctionExecuted = stopFunction && this.functionsExecuted.has(stopFunction);
5063
- if (lastMemItem.role === "function") {
5064
- if (!stopFunction || !stopFunctionExecuted) {
5065
- continue multiStepLoop;
5066
- }
5067
- }
5068
- if (!stopFunctionExecuted) {
5069
- assertRequiredFields(this.signature, output);
5070
- }
5297
+ const shouldContinue = this.shouldContinueSteps(
5298
+ lastMemItem,
5299
+ stopFunction
5300
+ );
5301
+ if (shouldContinue) {
5302
+ continue multiStepLoop;
5071
5303
  }
5072
- this.trace = { ...values, ...output };
5073
- return output;
5304
+ return;
5074
5305
  } catch (e) {
5075
5306
  let errorFields;
5076
5307
  span?.recordException(e);
@@ -5085,23 +5316,13 @@ var AxGen = class extends AxProgramWithSignature {
5085
5316
  throw e;
5086
5317
  }
5087
5318
  if (errorFields) {
5088
- mem.add(
5089
- {
5090
- role: "user",
5091
- content: this.promptTemplate.renderExtraFields(errorFields)
5092
- },
5093
- options?.sessionId
5319
+ handleValidationError(
5320
+ mem,
5321
+ errorFields,
5322
+ ai,
5323
+ this.promptTemplate,
5324
+ options.sessionId
5094
5325
  );
5095
- mem.addTag("error");
5096
- if (ai.getOptions().debug) {
5097
- process.stdout.write(
5098
- colorLog4.red(
5099
- `Error Correction:
5100
- ${JSON.stringify(errorFields, null, 2)}
5101
- `
5102
- )
5103
- );
5104
- }
5105
5326
  }
5106
5327
  }
5107
5328
  }
@@ -5112,35 +5333,68 @@ ${JSON.stringify(errorFields, null, 2)}
5112
5333
  }
5113
5334
  throw new Error(`Max steps reached: ${maxSteps}`);
5114
5335
  }
5115
- async forward(ai, values, options) {
5336
+ shouldContinueSteps(lastMemItem, stopFunction) {
5337
+ const stopFunctionExecuted = stopFunction && this.functionsExecuted.has(stopFunction);
5338
+ if (lastMemItem?.role === "function" && stopFunction && stopFunctionExecuted) {
5339
+ return false;
5340
+ }
5341
+ if (lastMemItem?.role === "function") {
5342
+ return true;
5343
+ }
5344
+ return false;
5345
+ }
5346
+ async *_forward1(ai, values, options) {
5116
5347
  const tracer = this.options?.tracer ?? options?.tracer;
5117
5348
  let functions = this.functions;
5118
5349
  if (options?.functions) {
5119
5350
  functions = parseFunctions(options.functions, this.functions);
5120
5351
  }
5121
5352
  if (!tracer) {
5122
- return await this._forward(ai, values, {
5353
+ yield* this._forward2(ai, values, {
5123
5354
  ...options,
5124
5355
  functions
5125
5356
  });
5357
+ return;
5126
5358
  }
5127
5359
  const funcNames = functions?.map((f) => f.name).join(",");
5128
5360
  const attributes = {
5129
5361
  ["generate.signature"]: this.signature.toString(),
5130
5362
  ["generate.functions"]: funcNames ?? ""
5131
5363
  };
5132
- return await tracer.startActiveSpan(
5133
- "Generate",
5134
- {
5135
- kind: SpanKind2.SERVER,
5136
- attributes
5137
- },
5138
- async (span) => {
5139
- const res = this._forward(ai, values, options, span);
5140
- span.end();
5141
- return res;
5142
- }
5143
- );
5364
+ const span = tracer.startSpan("Generate", {
5365
+ kind: SpanKind2.SERVER,
5366
+ attributes
5367
+ });
5368
+ try {
5369
+ yield* this._forward2(
5370
+ ai,
5371
+ values,
5372
+ {
5373
+ ...options,
5374
+ functions
5375
+ },
5376
+ span
5377
+ );
5378
+ } finally {
5379
+ span.end();
5380
+ }
5381
+ }
5382
+ async forward(ai, values, options) {
5383
+ const generator = this._forward1(ai, values, {
5384
+ ...options
5385
+ });
5386
+ let buffer = {};
5387
+ for await (const delta of generator) {
5388
+ buffer = mergeDeltas(buffer, delta.delta);
5389
+ }
5390
+ this.trace = { ...values, ...buffer };
5391
+ return buffer;
5392
+ }
5393
+ async *streamingForward(ai, values, options) {
5394
+ yield* this._forward1(ai, values, {
5395
+ ...options,
5396
+ stream: true
5397
+ });
5144
5398
  }
5145
5399
  };
5146
5400
 
@@ -5230,7 +5484,7 @@ var AxAgent = class {
5230
5484
  func: wrappedFunc
5231
5485
  };
5232
5486
  }
5233
- async forward(ai, values, options) {
5487
+ init(ai, options) {
5234
5488
  const _ai = this.ai ?? ai;
5235
5489
  const funcs = [
5236
5490
  ...options?.functions ?? [],
@@ -5241,26 +5495,15 @@ var AxAgent = class {
5241
5495
  const opt2 = { ...options, functions: funcs };
5242
5496
  this.program = new AxGen(this.signature, opt2);
5243
5497
  }
5244
- if (!options?.tracer) {
5245
- return await this.program.forward(_ai, values, opt);
5246
- }
5247
- const attributes = {
5248
- ["agent.name"]: this.name,
5249
- ["agent.description"]: this.description,
5250
- ["agent.subAgents"]: this.subAgentList ?? "none"
5251
- };
5252
- return await options?.tracer.startActiveSpan(
5253
- "Agent",
5254
- {
5255
- kind: SpanKind3.SERVER,
5256
- attributes
5257
- },
5258
- async (span) => {
5259
- const res = await this.program.forward(_ai, values, opt);
5260
- span.end();
5261
- return res;
5262
- }
5263
- );
5498
+ return { _ai, opt };
5499
+ }
5500
+ async forward(ai, values, options) {
5501
+ const { _ai, opt } = this.init(ai, options);
5502
+ return await this.program.forward(_ai, values, opt);
5503
+ }
5504
+ async *streamingForward(ai, values, options) {
5505
+ const { _ai, opt } = this.init(ai, options);
5506
+ return yield* this.program.streamingForward(_ai, values, opt);
5264
5507
  }
5265
5508
  };
5266
5509
  function toCamelCase(inputString) {
@@ -5531,7 +5774,7 @@ var randomSample = (array, n) => {
5531
5774
  };
5532
5775
 
5533
5776
  // db/base.ts
5534
- import { SpanKind as SpanKind4 } from "@opentelemetry/api";
5777
+ import { SpanKind as SpanKind3 } from "@opentelemetry/api";
5535
5778
  var AxDBBase = class {
5536
5779
  name;
5537
5780
  fetch;
@@ -5558,7 +5801,7 @@ var AxDBBase = class {
5558
5801
  return await this.tracer?.startActiveSpan(
5559
5802
  "DB Upsert Request",
5560
5803
  {
5561
- kind: SpanKind4.SERVER,
5804
+ kind: SpanKind3.SERVER,
5562
5805
  attributes: {
5563
5806
  [axSpanAttributes.DB_SYSTEM]: this.name,
5564
5807
  [axSpanAttributes.DB_OPERATION_NAME]: "upsert",
@@ -5568,9 +5811,11 @@ var AxDBBase = class {
5568
5811
  }
5569
5812
  },
5570
5813
  async (span) => {
5571
- const res = await this._upsert(req, update, { span });
5572
- span.end();
5573
- return res;
5814
+ try {
5815
+ return await this._upsert(req, update, { span });
5816
+ } finally {
5817
+ span.end();
5818
+ }
5574
5819
  }
5575
5820
  );
5576
5821
  }
@@ -5590,7 +5835,7 @@ var AxDBBase = class {
5590
5835
  return await this.tracer?.startActiveSpan(
5591
5836
  "DB Batch Upsert Request",
5592
5837
  {
5593
- kind: SpanKind4.SERVER,
5838
+ kind: SpanKind3.SERVER,
5594
5839
  attributes: {
5595
5840
  [axSpanAttributes.DB_SYSTEM]: this.name,
5596
5841
  [axSpanAttributes.DB_OPERATION_NAME]: "upsert",
@@ -5600,9 +5845,11 @@ var AxDBBase = class {
5600
5845
  }
5601
5846
  },
5602
5847
  async (span) => {
5603
- const res = await this._batchUpsert(req, update, { span });
5604
- span.end();
5605
- return res;
5848
+ try {
5849
+ return await this._batchUpsert(req, update, { span });
5850
+ } finally {
5851
+ span.end();
5852
+ }
5606
5853
  }
5607
5854
  );
5608
5855
  }
@@ -5616,7 +5863,7 @@ var AxDBBase = class {
5616
5863
  return await this.tracer?.startActiveSpan(
5617
5864
  "DB Query Request",
5618
5865
  {
5619
- kind: SpanKind4.SERVER,
5866
+ kind: SpanKind3.SERVER,
5620
5867
  attributes: {
5621
5868
  [axSpanAttributes.DB_SYSTEM]: this.name,
5622
5869
  [axSpanAttributes.DB_OPERATION_NAME]: "upsert",
@@ -5626,9 +5873,11 @@ var AxDBBase = class {
5626
5873
  }
5627
5874
  },
5628
5875
  async (span) => {
5629
- const res = await this._query(req, { span });
5630
- span.end();
5631
- return res;
5876
+ try {
5877
+ return await this._query(req, { span });
5878
+ } finally {
5879
+ span.end();
5880
+ }
5632
5881
  }
5633
5882
  );
5634
5883
  }
@@ -6895,6 +7144,122 @@ var AxEmbeddingAdapter = class {
6895
7144
  }
6896
7145
  };
6897
7146
 
7147
+ // ai/mock/api.ts
7148
+ var AxMockAIService = class {
7149
+ constructor(config = {}) {
7150
+ this.config = config;
7151
+ }
7152
+ options = {};
7153
+ metrics = {
7154
+ latency: {
7155
+ chat: { mean: 0, p95: 0, p99: 0, samples: [] },
7156
+ embed: { mean: 0, p95: 0, p99: 0, samples: [] }
7157
+ },
7158
+ errors: {
7159
+ chat: { count: 0, rate: 0, total: 0 },
7160
+ embed: { count: 0, rate: 0, total: 0 }
7161
+ }
7162
+ };
7163
+ getName() {
7164
+ return this.config.name ?? "mock-ai-service";
7165
+ }
7166
+ getModelInfo() {
7167
+ return {
7168
+ name: "mock-model",
7169
+ provider: "mock-provider",
7170
+ promptTokenCostPer1M: 100,
7171
+ completionTokenCostPer1M: 100,
7172
+ ...this.config.modelInfo
7173
+ };
7174
+ }
7175
+ getEmbedModelInfo() {
7176
+ return this.config.embedModelInfo;
7177
+ }
7178
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
7179
+ getFeatures(_model) {
7180
+ return {
7181
+ functions: this.config.features?.functions ?? false,
7182
+ streaming: this.config.features?.streaming ?? false
7183
+ };
7184
+ }
7185
+ getModelMap() {
7186
+ return this.config.modelMap;
7187
+ }
7188
+ getMetrics() {
7189
+ return this.metrics;
7190
+ }
7191
+ async chat(req, _options) {
7192
+ if (this.config.latencyMs) {
7193
+ await new Promise((resolve) => setTimeout(resolve, this.config.latencyMs));
7194
+ }
7195
+ if (this.config.shouldError) {
7196
+ throw new Error(this.config.errorMessage ?? "Mock chat error");
7197
+ }
7198
+ this.updateMetrics("chat");
7199
+ if (typeof this.config.chatResponse === "function") {
7200
+ return this.config.chatResponse(req);
7201
+ }
7202
+ return this.config.chatResponse ?? {
7203
+ results: [
7204
+ {
7205
+ content: "Mock response",
7206
+ finishReason: "stop"
7207
+ }
7208
+ ],
7209
+ modelUsage: {
7210
+ promptTokens: 10,
7211
+ completionTokens: 5,
7212
+ totalTokens: 15
7213
+ }
7214
+ };
7215
+ }
7216
+ async embed(req, _options) {
7217
+ if (this.config.latencyMs) {
7218
+ await new Promise((resolve) => setTimeout(resolve, this.config.latencyMs));
7219
+ }
7220
+ if (this.config.shouldError) {
7221
+ throw new Error(this.config.errorMessage ?? "Mock embed error");
7222
+ }
7223
+ this.updateMetrics("embed");
7224
+ if (typeof this.config.embedResponse === "function") {
7225
+ return this.config.embedResponse(req);
7226
+ }
7227
+ return this.config.embedResponse ?? {
7228
+ embeddings: [[0.1, 0.2, 0.3]],
7229
+ modelUsage: {
7230
+ promptTokens: 5,
7231
+ completionTokens: 0,
7232
+ totalTokens: 5
7233
+ }
7234
+ };
7235
+ }
7236
+ setOptions(options) {
7237
+ this.options = options;
7238
+ }
7239
+ getOptions() {
7240
+ return this.options;
7241
+ }
7242
+ updateMetrics(type) {
7243
+ const latency = this.config.latencyMs ?? 0;
7244
+ this.metrics.latency[type].samples.push(latency);
7245
+ const samples = this.metrics.latency[type].samples;
7246
+ this.metrics.latency[type].mean = samples.reduce((a, b) => a + b, 0) / samples.length;
7247
+ if (samples.length > 0) {
7248
+ const sortedSamples = [...samples].sort((a, b) => a - b);
7249
+ const p95Index = Math.max(0, Math.floor(sortedSamples.length * 0.95) - 1);
7250
+ this.metrics.latency[type].p95 = sortedSamples[p95Index] ?? latency;
7251
+ const p99Index = Math.max(0, Math.floor(sortedSamples.length * 0.99) - 1);
7252
+ this.metrics.latency[type].p99 = sortedSamples[p99Index] ?? latency;
7253
+ }
7254
+ if (this.config.shouldError) {
7255
+ this.metrics.errors[type].count++;
7256
+ this.metrics.errors[type].total++;
7257
+ const totalRequests = this.metrics.latency[type].samples.length;
7258
+ this.metrics.errors[type].rate = totalRequests > 0 ? this.metrics.errors[type].count / totalRequests : 0;
7259
+ }
7260
+ }
7261
+ };
7262
+
6898
7263
  // prompts/rag.ts
6899
7264
  var AxRAG = class extends AxChainOfThought {
6900
7265
  genQuery;
@@ -6983,6 +7348,7 @@ export {
6983
7348
  AxJSInterpreterPermission,
6984
7349
  AxLLMRequestTypeValues,
6985
7350
  AxMemory,
7351
+ AxMockAIService,
6986
7352
  AxProgram,
6987
7353
  AxProgramWithSignature,
6988
7354
  AxPromptTemplate,