@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.cjs CHANGED
@@ -84,6 +84,7 @@ __export(index_exports, {
84
84
  AxJSInterpreterPermission: () => AxJSInterpreterPermission,
85
85
  AxLLMRequestTypeValues: () => AxLLMRequestTypeValues,
86
86
  AxMemory: () => AxMemory,
87
+ AxMockAIService: () => AxMockAIService,
87
88
  AxProgram: () => AxProgram,
88
89
  AxProgramWithSignature: () => AxProgramWithSignature,
89
90
  AxPromptTemplate: () => AxPromptTemplate,
@@ -618,9 +619,11 @@ var AxBaseAI = class {
618
619
  }
619
620
  },
620
621
  async (span) => {
621
- const res = await this._chat2(model, modelConfig, req, options, span);
622
- span.end();
623
- return res;
622
+ try {
623
+ return await this._chat2(model, modelConfig, req, options, span);
624
+ } finally {
625
+ span.end();
626
+ }
624
627
  }
625
628
  );
626
629
  }
@@ -649,7 +652,7 @@ var AxBaseAI = class {
649
652
  {
650
653
  name: apiConfig.name,
651
654
  url: this.apiURL,
652
- headers: this.buildHeaders(apiConfig.headers),
655
+ headers: await this.buildHeaders(apiConfig.headers),
653
656
  stream: modelConfig.stream,
654
657
  debug: this.debug,
655
658
  fetch: this.fetch,
@@ -743,9 +746,11 @@ var AxBaseAI = class {
743
746
  }
744
747
  },
745
748
  async (span) => {
746
- const res = await this._embed2(embedModel, req, options, span);
747
- span.end();
748
- return res;
749
+ try {
750
+ return await this._embed2(embedModel, req, options, span);
751
+ } finally {
752
+ span.end();
753
+ }
749
754
  }
750
755
  );
751
756
  }
@@ -768,7 +773,7 @@ var AxBaseAI = class {
768
773
  {
769
774
  name: apiConfig.name,
770
775
  url: this.apiURL,
771
- headers: this.buildHeaders(apiConfig.headers),
776
+ headers: await this.buildHeaders(apiConfig.headers),
772
777
  debug: this.debug,
773
778
  fetch: this.fetch,
774
779
  span
@@ -792,8 +797,8 @@ var AxBaseAI = class {
792
797
  span?.end();
793
798
  return res;
794
799
  }
795
- buildHeaders(headers = {}) {
796
- return { ...headers, ...this.headers };
800
+ async buildHeaders(headers = {}) {
801
+ return { ...headers, ...await this.headers() };
797
802
  }
798
803
  };
799
804
  var logChatRequest = (req) => {
@@ -813,7 +818,7 @@ ${colorLog.whiteBright(msg.content)}`;
813
818
  const items2 = msg.content.map((v) => {
814
819
  switch (v.type) {
815
820
  case "text":
816
- return `(Text) ${colorLog.whiteBright(v.text)}`;
821
+ return `${colorLog.whiteBright(v.text)}`;
817
822
  case "image":
818
823
  return `(Image, ${v.mimeType}) ${colorLog.whiteBright(v.image.substring(0, 10))}`;
819
824
  default:
@@ -968,6 +973,30 @@ var AxAIAnthropicImpl = class {
968
973
  const apiConfig = {
969
974
  name: "/messages"
970
975
  };
976
+ let toolsChoice;
977
+ if (req.functionCall && req.functions && req.functions.length > 0) {
978
+ if (typeof req.functionCall === "string") {
979
+ switch (req.functionCall) {
980
+ case "auto":
981
+ toolsChoice = { tool_choice: { type: "auto" } };
982
+ break;
983
+ case "required":
984
+ toolsChoice = { tool_choice: { type: "any" } };
985
+ break;
986
+ case "none":
987
+ throw new Error("functionCall none not supported");
988
+ }
989
+ } else if ("function" in req.functionCall) {
990
+ toolsChoice = {
991
+ tool_choice: {
992
+ type: "tool",
993
+ name: req.functionCall.function.name
994
+ }
995
+ };
996
+ } else {
997
+ throw new Error("Invalid function call type, must be string or object");
998
+ }
999
+ }
971
1000
  const system = req.chatPrompt.filter((msg) => msg.role === "system").map((msg) => ({
972
1001
  type: "text",
973
1002
  text: msg.content,
@@ -990,7 +1019,8 @@ var AxAIAnthropicImpl = class {
990
1019
  temperature: req.modelConfig?.temperature ?? this.config.temperature,
991
1020
  top_p: req.modelConfig?.topP ?? this.config.topP,
992
1021
  top_k: req.modelConfig?.topK ?? this.config.topK,
993
- ...tools && tools.length > 0 ? { tools, tool_choice: { type: "auto" } } : {},
1022
+ ...toolsChoice,
1023
+ ...tools && tools.length > 0 ? { tools } : {},
994
1024
  ...stream ? { stream: true } : {},
995
1025
  ...system ? { system } : {},
996
1026
  messages
@@ -1153,11 +1183,11 @@ var AxAIAnthropic = class extends AxBaseAI {
1153
1183
  super(aiImpl, {
1154
1184
  name: "Anthropic",
1155
1185
  apiURL: "https://api.anthropic.com/v1",
1156
- headers: {
1186
+ headers: async () => ({
1157
1187
  "anthropic-version": "2023-06-01",
1158
1188
  "anthropic-beta": "prompt-caching-2024-07-31",
1159
1189
  "x-api-key": apiKey
1160
- },
1190
+ }),
1161
1191
  modelInfo: axModelInfoAnthropic,
1162
1192
  models: { model: _config.model },
1163
1193
  options,
@@ -1662,7 +1692,7 @@ var AxAIOpenAI = class extends AxBaseAI {
1662
1692
  super(aiImpl, {
1663
1693
  name: "OpenAI",
1664
1694
  apiURL: apiURL ? apiURL : "https://api.openai.com/v1",
1665
- headers: { Authorization: `Bearer ${apiKey}` },
1695
+ headers: async () => ({ Authorization: `Bearer ${apiKey}` }),
1666
1696
  modelInfo,
1667
1697
  models: {
1668
1698
  model: _config.model,
@@ -1714,7 +1744,7 @@ var AxAIAzureOpenAI = class extends AxAIOpenAI {
1714
1744
  host
1715
1745
  ).href
1716
1746
  );
1717
- super.setHeaders({ "api-key": apiKey });
1747
+ super.setHeaders(async () => ({ "api-key": apiKey }));
1718
1748
  }
1719
1749
  };
1720
1750
 
@@ -1974,7 +2004,7 @@ var AxAICohere = class extends AxBaseAI {
1974
2004
  super(aiImpl, {
1975
2005
  name: "Cohere",
1976
2006
  apiURL: "https://api.cohere.ai/v1",
1977
- headers: { Authorization: `Bearer ${apiKey}` },
2007
+ headers: async () => ({ Authorization: `Bearer ${apiKey}` }),
1978
2008
  modelInfo: axModelInfoCohere,
1979
2009
  models: { model: _config.model },
1980
2010
  supportFor: { functions: true, streaming: true },
@@ -2094,6 +2124,61 @@ var AxAIDeepSeek = class extends AxAIOpenAI {
2094
2124
  }
2095
2125
  };
2096
2126
 
2127
+ // ai/google-gemini/auth.ts
2128
+ var import_google_auth_library = require("google-auth-library");
2129
+ var GoogleVertexAuth = class {
2130
+ auth;
2131
+ client;
2132
+ currentToken;
2133
+ tokenExpiry;
2134
+ constructor(config = {}) {
2135
+ this.auth = new import_google_auth_library.GoogleAuth({
2136
+ scopes: ["https://www.googleapis.com/auth/cloud-platform"],
2137
+ ...config
2138
+ });
2139
+ }
2140
+ async getAuthenticatedClient() {
2141
+ if (!this.client) {
2142
+ this.client = await this.auth.getClient();
2143
+ }
2144
+ return this.client;
2145
+ }
2146
+ async getAccessToken() {
2147
+ if (this.currentToken && this.tokenExpiry && Date.now() < this.tokenExpiry) {
2148
+ return this.currentToken;
2149
+ }
2150
+ const client = await this.getAuthenticatedClient();
2151
+ const tokenResponse = await client.getAccessToken();
2152
+ this.currentToken = tokenResponse.token ?? void 0;
2153
+ const expiry = this.getExpiry(tokenResponse);
2154
+ const fiveMinutes = 5 * 60 * 1e3;
2155
+ this.tokenExpiry = expiry - fiveMinutes;
2156
+ return this.currentToken;
2157
+ }
2158
+ /**
2159
+ * Get the expiry date from the token response.
2160
+ */
2161
+ getExpiry(tokenResponse) {
2162
+ const oneHour = 3600 * 1e3;
2163
+ let expiry = Date.now() + oneHour;
2164
+ let responseExpiry = tokenResponse.res?.data?.expiry_date;
2165
+ if (responseExpiry) {
2166
+ if (typeof responseExpiry === "number") {
2167
+ expiry = responseExpiry;
2168
+ } else if (responseExpiry instanceof Date) {
2169
+ expiry = responseExpiry.getTime();
2170
+ } else if (typeof responseExpiry === "string") {
2171
+ expiry = new Date(responseExpiry).getTime();
2172
+ } else {
2173
+ console.warn("Unknown expiry type", responseExpiry);
2174
+ }
2175
+ } else {
2176
+ console.warn("No expiry date found in response", tokenResponse.res?.data);
2177
+ }
2178
+ return expiry;
2179
+ }
2180
+ };
2181
+
2097
2182
  // ai/google-gemini/types.ts
2098
2183
  var AxAIGoogleGeminiModel = /* @__PURE__ */ ((AxAIGoogleGeminiModel2) => {
2099
2184
  AxAIGoogleGeminiModel2["Gemini1Pro"] = "gemini-1.0-pro";
@@ -2106,6 +2191,7 @@ var AxAIGoogleGeminiModel = /* @__PURE__ */ ((AxAIGoogleGeminiModel2) => {
2106
2191
  })(AxAIGoogleGeminiModel || {});
2107
2192
  var AxAIGoogleGeminiEmbedModel = /* @__PURE__ */ ((AxAIGoogleGeminiEmbedModel2) => {
2108
2193
  AxAIGoogleGeminiEmbedModel2["TextEmbedding004"] = "text-embedding-004";
2194
+ AxAIGoogleGeminiEmbedModel2["TextEmbedding005"] = "text-embedding-005";
2109
2195
  return AxAIGoogleGeminiEmbedModel2;
2110
2196
  })(AxAIGoogleGeminiEmbedModel || {});
2111
2197
  var AxAIGoogleGeminiSafetyCategory = /* @__PURE__ */ ((AxAIGoogleGeminiSafetyCategory2) => {
@@ -2182,10 +2268,11 @@ var axAIGoogleGeminiDefaultConfig = () => structuredClone({
2182
2268
  ...axBaseAIDefaultConfig()
2183
2269
  });
2184
2270
  var AxAIGoogleGeminiImpl = class {
2185
- constructor(config, apiKey, isVertex, options) {
2271
+ constructor(config, isVertex, apiKey, keyFile, options) {
2186
2272
  this.config = config;
2187
- this.apiKey = apiKey;
2188
2273
  this.isVertex = isVertex;
2274
+ this.apiKey = apiKey;
2275
+ this.keyFile = keyFile;
2189
2276
  this.options = options;
2190
2277
  }
2191
2278
  getModelConfig() {
@@ -2212,7 +2299,7 @@ var AxAIGoogleGeminiImpl = class {
2212
2299
  const apiConfig = {
2213
2300
  name: stream ? `/models/${model}:streamGenerateContent?alt=sse` : `/models/${model}:generateContent`
2214
2301
  };
2215
- if (this.isVertex === false) {
2302
+ if (!this.isVertex) {
2216
2303
  const pf = stream ? "&" : "?";
2217
2304
  apiConfig.name += `${pf}key=${this.apiKey}`;
2218
2305
  }
@@ -2359,15 +2446,28 @@ var AxAIGoogleGeminiImpl = class {
2359
2446
  if (!req.texts || req.texts.length === 0) {
2360
2447
  throw new Error("Embed texts is empty");
2361
2448
  }
2362
- const apiConfig = {
2363
- name: `/models/${model}:batchEmbedContents?key=${this.apiKey}`
2364
- };
2365
- const reqValue = {
2366
- requests: req.texts.map((text) => ({
2367
- model: "models/" + model,
2368
- content: { parts: [{ text }] }
2369
- }))
2370
- };
2449
+ let apiConfig;
2450
+ let reqValue;
2451
+ if (this.isVertex) {
2452
+ apiConfig = {
2453
+ name: `/models/${model}:predict`
2454
+ };
2455
+ reqValue = {
2456
+ instances: req.texts.map((text) => ({
2457
+ content: text
2458
+ }))
2459
+ };
2460
+ } else {
2461
+ apiConfig = {
2462
+ name: `/models/${model}:batchEmbedContents?key=${this.apiKey}`
2463
+ };
2464
+ reqValue = {
2465
+ requests: req.texts.map((text) => ({
2466
+ model: "models/" + model,
2467
+ content: { parts: [{ text }] }
2468
+ }))
2469
+ };
2470
+ }
2371
2471
  return [apiConfig, reqValue];
2372
2472
  };
2373
2473
  createChatResp = (resp) => {
@@ -2429,7 +2529,16 @@ var AxAIGoogleGeminiImpl = class {
2429
2529
  return this.createChatResp(resp);
2430
2530
  };
2431
2531
  createEmbedResp = (resp) => {
2432
- const embeddings = resp.embeddings.map((embedding) => embedding.values);
2532
+ let embeddings;
2533
+ if (this.isVertex) {
2534
+ embeddings = resp.predictions.map(
2535
+ (prediction) => prediction.embeddings.values
2536
+ );
2537
+ } else {
2538
+ embeddings = resp.embeddings.map(
2539
+ (embedding) => embedding.values
2540
+ );
2541
+ }
2433
2542
  return {
2434
2543
  embeddings
2435
2544
  };
@@ -2440,28 +2549,44 @@ var AxAIGoogleGemini = class extends AxBaseAI {
2440
2549
  apiKey,
2441
2550
  projectId,
2442
2551
  region,
2552
+ keyFile,
2443
2553
  config,
2444
2554
  options,
2445
2555
  modelMap
2446
2556
  }) {
2447
- if (!apiKey || apiKey === "") {
2448
- throw new Error("GoogleGemini AI API key not set");
2449
- }
2450
2557
  const isVertex = projectId !== void 0 && region !== void 0;
2451
2558
  let apiURL;
2452
2559
  let headers;
2453
2560
  if (isVertex) {
2454
2561
  apiURL = `https://${region}-aiplatform.googleapis.com/v1/projects/${projectId}/locations/${region}/publishers/google/`;
2455
- headers = { Authorization: `Bearer ${apiKey}` };
2562
+ if (apiKey) {
2563
+ headers = async () => ({ Authorization: `Bearer ${apiKey}` });
2564
+ } else {
2565
+ const vertexAuth = new GoogleVertexAuth({
2566
+ keyFile
2567
+ });
2568
+ headers = async () => ({
2569
+ Authorization: `Bearer ${await vertexAuth.getAccessToken()}`
2570
+ });
2571
+ }
2456
2572
  } else {
2573
+ if (!apiKey) {
2574
+ throw new Error("GoogleGemini AI API key not set");
2575
+ }
2457
2576
  apiURL = "https://generativelanguage.googleapis.com/v1beta";
2458
- headers = {};
2577
+ headers = async () => ({});
2459
2578
  }
2460
2579
  const _config = {
2461
2580
  ...axAIGoogleGeminiDefaultConfig(),
2462
2581
  ...config
2463
2582
  };
2464
- const aiImpl = new AxAIGoogleGeminiImpl(_config, apiKey, isVertex, options);
2583
+ const aiImpl = new AxAIGoogleGeminiImpl(
2584
+ _config,
2585
+ isVertex,
2586
+ apiKey,
2587
+ keyFile,
2588
+ options
2589
+ );
2465
2590
  super(aiImpl, {
2466
2591
  name: "GoogleGeminiAI",
2467
2592
  apiURL,
@@ -2731,7 +2856,7 @@ var AxAIHuggingFace = class extends AxBaseAI {
2731
2856
  super(aiImpl, {
2732
2857
  name: "HuggingFace",
2733
2858
  apiURL: "https://api-inference.huggingface.co",
2734
- headers: { Authorization: `Bearer ${apiKey}` },
2859
+ headers: async () => ({ Authorization: `Bearer ${apiKey}` }),
2735
2860
  modelInfo: axModelInfoHuggingFace,
2736
2861
  models: { model: _config.model },
2737
2862
  options,
@@ -3080,7 +3205,7 @@ var AxAIReka = class extends AxBaseAI {
3080
3205
  super(aiImpl, {
3081
3206
  name: "Reka",
3082
3207
  apiURL: apiURL ? apiURL : "https://api.reka.ai/v1/chat",
3083
- headers: { "X-Api-Key": apiKey },
3208
+ headers: async () => ({ "X-Api-Key": apiKey }),
3084
3209
  modelInfo,
3085
3210
  models: {
3086
3211
  model: _config.model
@@ -3204,9 +3329,6 @@ var AxAI = class {
3204
3329
  }
3205
3330
  };
3206
3331
 
3207
- // prompts/agent.ts
3208
- var import_api23 = require("@opentelemetry/api");
3209
-
3210
3332
  // dsp/generate.ts
3211
3333
  var import_web5 = require("stream/web");
3212
3334
  var import_api22 = require("@opentelemetry/api");
@@ -3395,7 +3517,7 @@ var AxAssertionError = class extends Error {
3395
3517
  extraFields.push({
3396
3518
  name: "error",
3397
3519
  title: "Error In Output",
3398
- description: this.message
3520
+ description: `You must follow the following instructions, "${this.message}".`
3399
3521
  });
3400
3522
  return extraFields;
3401
3523
  };
@@ -3434,18 +3556,6 @@ var assertStreamingAssertions = (asserts, values, xstate, content, final) => {
3434
3556
  }
3435
3557
  }
3436
3558
  };
3437
- var assertRequiredFields = (sig, values) => {
3438
- const fields = sig.getOutputFields();
3439
- const missingFields = fields.filter(
3440
- (f) => !f.isOptional && !(f.name in values)
3441
- );
3442
- if (missingFields.length > 0) {
3443
- throw new AxAssertionError({
3444
- message: `Output must include: ${missingFields.map((f) => `\`${f.title}:\``).join(", ")}`,
3445
- values
3446
- });
3447
- }
3448
- };
3449
3559
 
3450
3560
  // dsp/extract.ts
3451
3561
  var import_json5 = __toESM(require("json5"), 1);
@@ -3993,6 +4103,21 @@ var parseMarkdownList = (input) => {
3993
4103
  }
3994
4104
  return list;
3995
4105
  };
4106
+ function mergeDeltas(base, delta) {
4107
+ const merged = { ...base };
4108
+ for (const key in delta) {
4109
+ const baseValue = base[key];
4110
+ const deltaValue = delta[key];
4111
+ if (Array.isArray(baseValue) && Array.isArray(deltaValue)) {
4112
+ merged[key] = [...baseValue, ...deltaValue];
4113
+ } else if (typeof baseValue === "string" && typeof deltaValue === "string") {
4114
+ merged[key] = baseValue + deltaValue;
4115
+ } else {
4116
+ merged[key] = deltaValue;
4117
+ }
4118
+ }
4119
+ return merged;
4120
+ }
3996
4121
 
3997
4122
  // dsp/program.ts
3998
4123
  var AxProgramWithSignature = class {
@@ -4025,6 +4150,9 @@ var AxProgramWithSignature = class {
4025
4150
  async forward(_ai, _values, _options) {
4026
4151
  throw new Error("forward() not implemented");
4027
4152
  }
4153
+ async *streamingForward(_ai, _values, _options) {
4154
+ throw new Error("streamingForward() not implemented");
4155
+ }
4028
4156
  setId(id) {
4029
4157
  this.key = { id, custom: true };
4030
4158
  for (const child of this.children) {
@@ -4119,6 +4247,9 @@ var AxProgram = class {
4119
4247
  async forward(_ai, _values, _options) {
4120
4248
  throw new Error("forward() not implemented");
4121
4249
  }
4250
+ async *streamingForward(_ai, _values, _options) {
4251
+ throw new Error("streamingForward() not implemented");
4252
+ }
4122
4253
  setId(id) {
4123
4254
  this.key = { id, custom: true };
4124
4255
  for (const child of this.children) {
@@ -4216,9 +4347,10 @@ ${outputFields}`);
4216
4347
  task.push(formattingRules.trim());
4217
4348
  const desc = this.sig.getDescription();
4218
4349
  if (desc) {
4350
+ const capitalized = capitalizeFirstLetter(desc.trim());
4219
4351
  task.push(
4220
4352
  `## TASK DESCRIPTION
4221
- ${capitalizeFirstLetter(desc.endsWith(".") ? desc : desc + ".")}`
4353
+ ${capitalized.endsWith(".") ? capitalized : capitalized + "."}`
4222
4354
  );
4223
4355
  }
4224
4356
  this.task = {
@@ -4266,16 +4398,42 @@ ${capitalizeFirstLetter(desc.endsWith(".") ? desc : desc + ".")}`
4266
4398
  };
4267
4399
  renderExtraFields = (extraFields) => {
4268
4400
  const prompt = [];
4269
- if (extraFields && extraFields.length > 0) {
4270
- extraFields.forEach((field) => {
4271
- const fn = this.fieldTemplates?.[field.name] ?? this.defaultRenderInField;
4272
- prompt.push(...fn(field, field.description));
4273
- });
4274
- }
4275
- if (prompt.every((v) => v.type === "text")) {
4276
- return prompt.map((v) => v.text).join("\n\n");
4277
- }
4278
- return prompt.reduce(combineConsecutiveStrings("\n"), []);
4401
+ if (!extraFields || extraFields.length === 0) {
4402
+ return prompt;
4403
+ }
4404
+ const groupedFields = extraFields.reduce(
4405
+ (acc, field) => {
4406
+ const title = field.title;
4407
+ if (!acc[title]) {
4408
+ acc[title] = [];
4409
+ }
4410
+ acc[title].push(field);
4411
+ return acc;
4412
+ },
4413
+ {}
4414
+ );
4415
+ const formattedGroupedFields = Object.entries(groupedFields).map(([title, fields]) => {
4416
+ if (fields.length === 1) {
4417
+ const field = fields[0];
4418
+ return {
4419
+ title,
4420
+ name: field.name,
4421
+ description: field.description
4422
+ };
4423
+ } else if (fields.length > 1) {
4424
+ const valuesList = fields.map((field) => `- ${field.description}`).join("\n");
4425
+ return {
4426
+ title,
4427
+ name: fields[0].name,
4428
+ description: valuesList
4429
+ };
4430
+ }
4431
+ }).filter(Boolean);
4432
+ formattedGroupedFields.forEach((field) => {
4433
+ const fn = this.fieldTemplates?.[field.name] ?? this.defaultRenderInField;
4434
+ prompt.push(...fn(field, field.description));
4435
+ });
4436
+ return prompt;
4279
4437
  };
4280
4438
  renderExamples = (data) => {
4281
4439
  const list = [];
@@ -4524,34 +4682,47 @@ function capitalizeFirstLetter(str) {
4524
4682
  }
4525
4683
 
4526
4684
  // dsp/validate.ts
4685
+ var colorLog4 = new ColorLog();
4527
4686
  var ValidationError = class extends Error {
4528
- field;
4529
- value;
4687
+ fields;
4530
4688
  constructor({
4531
4689
  message,
4532
- field,
4533
- value
4690
+ fields
4534
4691
  }) {
4535
4692
  super(message);
4536
- this.field = field;
4537
- this.value = value;
4693
+ this.fields = fields;
4538
4694
  this.name = this.constructor.name;
4539
4695
  Error.captureStackTrace(this, this.constructor);
4540
4696
  }
4541
- getField = () => this.field;
4542
- getValue = () => this.value;
4697
+ getFields = () => this.fields;
4543
4698
  getFixingInstructions = () => {
4544
- const f = this.field;
4545
- const extraFields = [
4546
- {
4547
- name: `outputError`,
4548
- title: `Invalid Output Field`,
4549
- description: `Invalid format for field \`${f.title}\` of type \`${toFieldType(f.type)}\`, format should match: \`${f.description}\``
4550
- }
4551
- ];
4552
- return extraFields;
4699
+ return this.fields.map((field) => ({
4700
+ name: "outputError",
4701
+ title: "Error In Output",
4702
+ description: `Please fix and return the field \`${field.title}\` of type \`${toFieldType(field.type)}\`, ${this.message}.`
4703
+ }));
4553
4704
  };
4554
4705
  };
4706
+ function handleValidationError(mem, errorFields, ai, promptTemplate, sessionId) {
4707
+ mem.add(
4708
+ {
4709
+ role: "user",
4710
+ content: promptTemplate.renderExtraFields(errorFields)
4711
+ },
4712
+ sessionId
4713
+ );
4714
+ mem.addTag("error");
4715
+ if (ai.getOptions().debug) {
4716
+ process.stdout.write(
4717
+ colorLog4.red(
4718
+ `
4719
+ Error Correction:
4720
+ ${JSON.stringify(errorFields, null, 2)}
4721
+ `
4722
+ )
4723
+ );
4724
+ }
4725
+ }
4555
4726
 
4556
4727
  // dsp/datetime.ts
4557
4728
  function parseLLMFriendlyDate(field, dateStr) {
@@ -4559,7 +4730,7 @@ function parseLLMFriendlyDate(field, dateStr) {
4559
4730
  return _parseLLMFriendlyDate(dateStr);
4560
4731
  } catch (err) {
4561
4732
  const message = err.message;
4562
- throw new ValidationError({ field, message, value: dateStr });
4733
+ throw new ValidationError({ fields: [field], message, value: dateStr });
4563
4734
  }
4564
4735
  }
4565
4736
  function _parseLLMFriendlyDate(dateStr) {
@@ -4576,7 +4747,7 @@ function parseLLMFriendlyDateTime(field, dateStr) {
4576
4747
  return _parseLLMFriendlyDateTime(dateStr);
4577
4748
  } catch (err) {
4578
4749
  const message = err.message;
4579
- throw new ValidationError({ field, message, value: dateStr });
4750
+ throw new ValidationError({ fields: [field], message, value: dateStr });
4580
4751
  }
4581
4752
  }
4582
4753
  function _parseLLMFriendlyDateTime(dateTimeStr) {
@@ -4618,41 +4789,61 @@ var formatDateWithTimezone = (date) => {
4618
4789
 
4619
4790
  // dsp/extract.ts
4620
4791
  var extractValues = (sig, values, content) => {
4621
- const xstate = { s: -1 };
4792
+ const xstate = { extractedFields: [], s: -1 };
4622
4793
  streamingExtractValues(sig, values, xstate, content);
4623
- streamingExtractFinalValue(values, xstate, content);
4794
+ streamingExtractFinalValue(sig, values, xstate, content);
4795
+ };
4796
+ var checkMissingRequiredFields = (xstate, values, currentIndex) => {
4797
+ const missingFields = [];
4798
+ for (let i = 0; i < currentIndex; i++) {
4799
+ const field = xstate.extractedFields[i];
4800
+ if (field && !field.isOptional && values[field.name] === void 0) {
4801
+ missingFields.push(field);
4802
+ }
4803
+ }
4804
+ if (missingFields.length > 0) {
4805
+ throw new ValidationError({
4806
+ message: `Required ${missingFields.length === 1 ? "field" : "fields"} not found`,
4807
+ fields: missingFields
4808
+ });
4809
+ }
4624
4810
  };
4625
- var streamingExtractValues = (sig, values, state, content) => {
4811
+ var streamingExtractValues = (sig, values, xstate, content) => {
4626
4812
  const fields = sig.getOutputFields();
4627
- for (const field of fields) {
4813
+ for (const [index, field] of fields.entries()) {
4628
4814
  if (field.name in values) {
4629
4815
  continue;
4630
4816
  }
4631
4817
  const prefix = field.title + ":";
4632
- const e = content.indexOf(prefix, state.s + 1);
4818
+ const e = content.indexOf(prefix, xstate.s + 1);
4633
4819
  if (e === -1) {
4634
4820
  continue;
4635
4821
  }
4636
- if (state.currField) {
4637
- const val = content.substring(state.s, e).trim().replace(/---+$/, "").trim();
4638
- values[state.currField.name] = validateAndParseFieldValue(
4639
- state.currField,
4640
- val
4641
- );
4822
+ if (xstate.currField) {
4823
+ const val = content.substring(xstate.s, e);
4824
+ const parsedValue = validateAndParseFieldValue(xstate.currField, val);
4825
+ if (parsedValue !== void 0) {
4826
+ values[xstate.currField.name] = parsedValue;
4827
+ }
4828
+ }
4829
+ checkMissingRequiredFields(xstate, values, index);
4830
+ xstate.s = e + prefix.length;
4831
+ xstate.currField = field;
4832
+ if (!xstate.extractedFields.includes(field)) {
4833
+ xstate.extractedFields.push(field);
4642
4834
  }
4643
- state.s = e + prefix.length;
4644
- state.currField = field;
4645
4835
  }
4646
4836
  };
4647
- var streamingExtractFinalValue = (values, state, content) => {
4648
- if (!state.currField) {
4649
- return;
4837
+ var streamingExtractFinalValue = (sig, values, xstate, content) => {
4838
+ if (xstate.currField) {
4839
+ const val = content.substring(xstate.s);
4840
+ const parsedValue = validateAndParseFieldValue(xstate.currField, val);
4841
+ if (parsedValue !== void 0) {
4842
+ values[xstate.currField.name] = parsedValue;
4843
+ }
4650
4844
  }
4651
- const val = content.substring(state.s).trim().replace(/---+$/, "").trim();
4652
- values[state.currField.name] = validateAndParseFieldValue(
4653
- state.currField,
4654
- val
4655
- );
4845
+ const fields = sig.getOutputFields();
4846
+ checkMissingRequiredFields(xstate, values, fields.length - 1);
4656
4847
  };
4657
4848
  var convertValueToType = (field, val) => {
4658
4849
  switch (field.type?.name) {
@@ -4690,59 +4881,98 @@ var convertValueToType = (field, val) => {
4690
4881
  return val;
4691
4882
  }
4692
4883
  };
4693
- var expectedTypeError = (field, err, value = "") => {
4694
- const exp = field.type?.isArray ? `array of ${field.type.name}` : field.type?.name;
4695
- const message = `Error '${err.message}', expected '${exp}' got '${value}'`;
4696
- return new ValidationError({ message, field, value });
4697
- };
4884
+ function* streamingValues(sig, values, xstate, content) {
4885
+ if (!xstate.currField) {
4886
+ return;
4887
+ }
4888
+ const fieldName = xstate.currField.name;
4889
+ if (!xstate.streamedIndex) {
4890
+ xstate.streamedIndex = { [fieldName]: 0 };
4891
+ }
4892
+ if (!xstate.currField.type || !xstate.currField.type.isArray && xstate.currField.type.name === "string") {
4893
+ const s = xstate.s + (xstate.streamedIndex[fieldName] ?? 0);
4894
+ const v = content.substring(s);
4895
+ yield { [fieldName]: v };
4896
+ xstate.streamedIndex[fieldName] = v.length;
4897
+ return;
4898
+ }
4899
+ for (const key of Object.keys(values)) {
4900
+ const value = values[key];
4901
+ if (Array.isArray(value)) {
4902
+ const s = xstate.streamedIndex[fieldName] ?? 0;
4903
+ const v = value.slice(s);
4904
+ if (v) {
4905
+ yield { [fieldName]: v };
4906
+ xstate.streamedIndex[fieldName] = s + 1;
4907
+ }
4908
+ continue;
4909
+ }
4910
+ if (!xstate.streamedIndex[fieldName]) {
4911
+ yield { [fieldName]: value };
4912
+ xstate.streamedIndex[fieldName] = 1;
4913
+ }
4914
+ }
4915
+ }
4698
4916
  function validateAndParseFieldValue(field, fieldValue) {
4699
- const fv = fieldValue?.toLocaleLowerCase();
4700
- if (!fieldValue || !fv || fv === "" || fv === "null" || fv === "undefined") {
4917
+ const fv = fieldValue?.trim();
4918
+ if (!fv || !fv || fv === "" || fv === "null" || fv === "NULL" || fv === "undefined") {
4701
4919
  if (field.isOptional) {
4702
4920
  return;
4703
4921
  }
4704
- throw expectedTypeError(field, new Error("Empty value"), fieldValue);
4922
+ throw new ValidationError({
4923
+ message: "Required field is missing",
4924
+ fields: [field],
4925
+ value: fv
4926
+ });
4705
4927
  }
4706
- let value = fieldValue;
4928
+ let value;
4707
4929
  if (field.type?.name === "json") {
4708
4930
  try {
4709
- const text = extractBlock(fieldValue);
4931
+ const text = extractBlock(fv);
4710
4932
  value = import_json5.default.parse(text);
4711
4933
  return value;
4712
4934
  } catch (e) {
4713
- throw expectedTypeError(field, e, fieldValue);
4935
+ throw new ValidationError({
4936
+ message: "Invalid JSON: " + e.message,
4937
+ fields: [field],
4938
+ value: fv
4939
+ });
4714
4940
  }
4715
4941
  }
4716
4942
  if (field.type?.isArray) {
4717
4943
  try {
4718
4944
  try {
4719
- value = import_json5.default.parse(fieldValue);
4945
+ value = import_json5.default.parse(fv);
4720
4946
  } catch {
4721
- value = parseMarkdownList(fieldValue);
4947
+ value = parseMarkdownList(fv);
4722
4948
  }
4723
4949
  if (!Array.isArray(value)) {
4724
4950
  throw new Error("Expected an array");
4725
4951
  }
4726
4952
  } catch (e) {
4727
- throw expectedTypeError(field, e, fieldValue);
4953
+ throw new ValidationError({
4954
+ message: "Invalid array: " + e.message,
4955
+ fields: [field],
4956
+ value: fv
4957
+ });
4728
4958
  }
4729
4959
  }
4730
- if (Array.isArray(value)) {
4731
- for (const [index, item] of value.entries()) {
4732
- try {
4960
+ try {
4961
+ if (Array.isArray(value)) {
4962
+ for (const [index, item] of value.entries()) {
4733
4963
  value[index] = convertValueToType(field, item);
4734
- } catch (e) {
4735
- throw expectedTypeError(field, e, item);
4736
4964
  }
4965
+ } else {
4966
+ value = convertValueToType(field, fv);
4737
4967
  }
4738
- } else {
4739
- try {
4740
- value = convertValueToType(field, fieldValue);
4741
- } catch (e) {
4742
- throw expectedTypeError(field, e, fieldValue);
4743
- }
4968
+ } catch (e) {
4969
+ throw new ValidationError({
4970
+ message: e.message,
4971
+ fields: [field],
4972
+ value: fieldValue
4973
+ });
4744
4974
  }
4745
- return value;
4975
+ return value ?? fv;
4746
4976
  }
4747
4977
  var extractBlock = (input) => {
4748
4978
  const jsonBlockPattern = /```([A-Za-z]+)?\s*([\s\S]*?)\s*```/g;
@@ -4909,7 +5139,6 @@ function parseFunctionCalls(ai, functionCalls, values, model) {
4909
5139
  }
4910
5140
 
4911
5141
  // dsp/generate.ts
4912
- var colorLog4 = new ColorLog();
4913
5142
  var AxGen = class extends AxProgramWithSignature {
4914
5143
  promptTemplate;
4915
5144
  asserts;
@@ -4974,7 +5203,7 @@ var AxGen = class extends AxProgramWithSignature {
4974
5203
  );
4975
5204
  return res;
4976
5205
  }
4977
- async forwardCore({
5206
+ async *forwardCore({
4978
5207
  ai,
4979
5208
  mem,
4980
5209
  options
@@ -4990,7 +5219,18 @@ var AxGen = class extends AxProgramWithSignature {
4990
5219
  options
4991
5220
  });
4992
5221
  if (res instanceof import_web5.ReadableStream) {
4993
- return await this.processSteamingResponse({
5222
+ yield* this.processStreamingResponse({
5223
+ ai,
5224
+ model,
5225
+ res,
5226
+ usageInfo,
5227
+ mem,
5228
+ traceId,
5229
+ sessionId,
5230
+ functions
5231
+ });
5232
+ } else {
5233
+ yield await this.processResponse({
4994
5234
  ai,
4995
5235
  model,
4996
5236
  res,
@@ -5001,18 +5241,8 @@ var AxGen = class extends AxProgramWithSignature {
5001
5241
  functions
5002
5242
  });
5003
5243
  }
5004
- return await this.processResponse({
5005
- ai,
5006
- model,
5007
- res,
5008
- usageInfo,
5009
- mem,
5010
- traceId,
5011
- sessionId,
5012
- functions
5013
- });
5014
5244
  }
5015
- async processSteamingResponse({
5245
+ async *processStreamingResponse({
5016
5246
  ai,
5017
5247
  model,
5018
5248
  res,
@@ -5024,36 +5254,39 @@ var AxGen = class extends AxProgramWithSignature {
5024
5254
  }) {
5025
5255
  const functionCalls = [];
5026
5256
  const values = {};
5027
- const xstate = { s: -1 };
5257
+ const xstate = { extractedFields: [], s: -1 };
5028
5258
  let content = "";
5029
5259
  for await (const v of res) {
5030
- for (const result of v.results ?? []) {
5031
- if (v.modelUsage) {
5032
- this.usage.push({ ...usageInfo, ...v.modelUsage });
5033
- }
5034
- if (result.content) {
5035
- content += result.content;
5036
- mem.updateResult({ name: result.name, content }, sessionId);
5037
- assertStreamingAssertions(
5038
- this.streamingAsserts,
5039
- values,
5040
- xstate,
5041
- content,
5042
- false
5043
- );
5044
- streamingExtractValues(this.signature, values, xstate, content);
5045
- assertAssertions(this.asserts, values);
5046
- }
5047
- if (result.functionCalls) {
5048
- mergeFunctionCalls(functionCalls, result.functionCalls);
5049
- mem.updateResult(
5050
- { name: result.name, content, functionCalls },
5051
- sessionId
5052
- );
5053
- }
5054
- if (result.finishReason === "length") {
5055
- throw new Error("Max tokens reached before completion");
5056
- }
5260
+ const result = v.results[0];
5261
+ if (!result) {
5262
+ continue;
5263
+ }
5264
+ if (v.modelUsage) {
5265
+ this.usage.push({ ...usageInfo, ...v.modelUsage });
5266
+ }
5267
+ if (result.content) {
5268
+ content += result.content;
5269
+ mem.updateResult({ name: result.name, content }, sessionId);
5270
+ assertStreamingAssertions(
5271
+ this.streamingAsserts,
5272
+ values,
5273
+ xstate,
5274
+ content,
5275
+ false
5276
+ );
5277
+ streamingExtractValues(this.signature, values, xstate, content);
5278
+ assertAssertions(this.asserts, values);
5279
+ yield* streamingValues(this.signature, values, xstate, content);
5280
+ }
5281
+ if (result.functionCalls) {
5282
+ mergeFunctionCalls(functionCalls, result.functionCalls);
5283
+ mem.updateResult(
5284
+ { name: result.name, content, functionCalls },
5285
+ sessionId
5286
+ );
5287
+ }
5288
+ if (result.finishReason === "length") {
5289
+ throw new Error("Max tokens reached before completion");
5057
5290
  }
5058
5291
  }
5059
5292
  const funcs = parseFunctionCalls(ai, functionCalls, values, model);
@@ -5071,7 +5304,6 @@ var AxGen = class extends AxProgramWithSignature {
5071
5304
  );
5072
5305
  this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
5073
5306
  }
5074
- streamingExtractFinalValue(values, xstate, content);
5075
5307
  assertStreamingAssertions(
5076
5308
  this.streamingAsserts,
5077
5309
  values,
@@ -5079,8 +5311,9 @@ var AxGen = class extends AxProgramWithSignature {
5079
5311
  content,
5080
5312
  true
5081
5313
  );
5314
+ streamingExtractFinalValue(this.signature, values, xstate, content);
5082
5315
  assertAssertions(this.asserts, values);
5083
- return { ...values };
5316
+ return values;
5084
5317
  }
5085
5318
  async processResponse({
5086
5319
  ai,
@@ -5092,45 +5325,47 @@ var AxGen = class extends AxProgramWithSignature {
5092
5325
  functions
5093
5326
  }) {
5094
5327
  const values = {};
5095
- for (const result of res.results ?? []) {
5096
- if (res.modelUsage) {
5097
- this.usage.push({ ...usageInfo, ...res.modelUsage });
5098
- }
5099
- mem.addResult(result, sessionId);
5100
- if (result.content) {
5101
- extractValues(this.signature, values, result.content);
5102
- assertAssertions(this.asserts, values);
5103
- }
5104
- if (result.functionCalls) {
5105
- const funcs = parseFunctionCalls(ai, result.functionCalls, values);
5106
- if (funcs) {
5107
- if (!functions) {
5108
- throw new Error("Functions are not defined");
5109
- }
5110
- const fx = await processFunctions(
5111
- ai,
5112
- functions,
5113
- funcs,
5114
- mem,
5115
- sessionId,
5116
- traceId
5117
- );
5118
- this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
5328
+ const result = res.results[0];
5329
+ if (!result) {
5330
+ throw new Error("No result found");
5331
+ }
5332
+ if (res.modelUsage) {
5333
+ this.usage.push({ ...usageInfo, ...res.modelUsage });
5334
+ }
5335
+ mem.addResult(result, sessionId);
5336
+ if (result.content) {
5337
+ extractValues(this.signature, values, result.content);
5338
+ assertAssertions(this.asserts, values);
5339
+ }
5340
+ if (result.functionCalls) {
5341
+ const funcs = parseFunctionCalls(ai, result.functionCalls, values);
5342
+ if (funcs) {
5343
+ if (!functions) {
5344
+ throw new Error("Functions are not defined");
5119
5345
  }
5120
- }
5121
- if (result.finishReason === "length") {
5122
- throw new Error("Max tokens reached before completion");
5346
+ const fx = await processFunctions(
5347
+ ai,
5348
+ functions,
5349
+ funcs,
5350
+ mem,
5351
+ sessionId,
5352
+ traceId
5353
+ );
5354
+ this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
5123
5355
  }
5124
5356
  }
5357
+ if (result.finishReason === "length") {
5358
+ throw new Error("Max tokens reached before completion");
5359
+ }
5125
5360
  return { ...values };
5126
5361
  }
5127
- async _forward(ai, values, options, span) {
5362
+ async *_forward2(ai, values, options, span) {
5128
5363
  const stopFunction = (options?.stopFunction ?? this.options?.stopFunction)?.toLowerCase();
5129
- const maxRetries = options?.maxRetries ?? this.options?.maxRetries ?? 3;
5130
- const maxSteps = options?.maxSteps ?? this.options?.maxSteps ?? 10;
5131
- const mem = options?.mem ?? this.options?.mem ?? new AxMemory();
5364
+ const maxRetries = options.maxRetries ?? this.options?.maxRetries ?? 10;
5365
+ const maxSteps = options.maxSteps ?? this.options?.maxSteps ?? 10;
5366
+ const mem = options.mem ?? this.options?.mem ?? new AxMemory();
5132
5367
  let err;
5133
- if (options?.functions && options?.functions.length > 0) {
5368
+ if (options?.functions && options.functions.length > 0) {
5134
5369
  const promptTemplate = this.options?.promptTemplate ?? AxPromptTemplate;
5135
5370
  this.promptTemplate = new promptTemplate(
5136
5371
  this.signature,
@@ -5145,25 +5380,22 @@ var AxGen = class extends AxProgramWithSignature {
5145
5380
  multiStepLoop: for (let n = 0; n < maxSteps; n++) {
5146
5381
  for (let errCount = 0; errCount < maxRetries; errCount++) {
5147
5382
  try {
5148
- const output = await this.forwardCore({
5149
- options,
5150
- ai,
5151
- mem
5152
- });
5383
+ const generator = this.forwardCore({ options, ai, mem });
5384
+ for await (const delta of generator) {
5385
+ yield {
5386
+ version: errCount,
5387
+ delta
5388
+ };
5389
+ }
5153
5390
  const lastMemItem = mem.getLast(options?.sessionId);
5154
- if (lastMemItem) {
5155
- const stopFunctionExecuted = stopFunction && this.functionsExecuted.has(stopFunction);
5156
- if (lastMemItem.role === "function") {
5157
- if (!stopFunction || !stopFunctionExecuted) {
5158
- continue multiStepLoop;
5159
- }
5160
- }
5161
- if (!stopFunctionExecuted) {
5162
- assertRequiredFields(this.signature, output);
5163
- }
5391
+ const shouldContinue = this.shouldContinueSteps(
5392
+ lastMemItem,
5393
+ stopFunction
5394
+ );
5395
+ if (shouldContinue) {
5396
+ continue multiStepLoop;
5164
5397
  }
5165
- this.trace = { ...values, ...output };
5166
- return output;
5398
+ return;
5167
5399
  } catch (e) {
5168
5400
  let errorFields;
5169
5401
  span?.recordException(e);
@@ -5178,23 +5410,13 @@ var AxGen = class extends AxProgramWithSignature {
5178
5410
  throw e;
5179
5411
  }
5180
5412
  if (errorFields) {
5181
- mem.add(
5182
- {
5183
- role: "user",
5184
- content: this.promptTemplate.renderExtraFields(errorFields)
5185
- },
5186
- options?.sessionId
5413
+ handleValidationError(
5414
+ mem,
5415
+ errorFields,
5416
+ ai,
5417
+ this.promptTemplate,
5418
+ options.sessionId
5187
5419
  );
5188
- mem.addTag("error");
5189
- if (ai.getOptions().debug) {
5190
- process.stdout.write(
5191
- colorLog4.red(
5192
- `Error Correction:
5193
- ${JSON.stringify(errorFields, null, 2)}
5194
- `
5195
- )
5196
- );
5197
- }
5198
5420
  }
5199
5421
  }
5200
5422
  }
@@ -5205,35 +5427,68 @@ ${JSON.stringify(errorFields, null, 2)}
5205
5427
  }
5206
5428
  throw new Error(`Max steps reached: ${maxSteps}`);
5207
5429
  }
5208
- async forward(ai, values, options) {
5430
+ shouldContinueSteps(lastMemItem, stopFunction) {
5431
+ const stopFunctionExecuted = stopFunction && this.functionsExecuted.has(stopFunction);
5432
+ if (lastMemItem?.role === "function" && stopFunction && stopFunctionExecuted) {
5433
+ return false;
5434
+ }
5435
+ if (lastMemItem?.role === "function") {
5436
+ return true;
5437
+ }
5438
+ return false;
5439
+ }
5440
+ async *_forward1(ai, values, options) {
5209
5441
  const tracer = this.options?.tracer ?? options?.tracer;
5210
5442
  let functions = this.functions;
5211
5443
  if (options?.functions) {
5212
5444
  functions = parseFunctions(options.functions, this.functions);
5213
5445
  }
5214
5446
  if (!tracer) {
5215
- return await this._forward(ai, values, {
5447
+ yield* this._forward2(ai, values, {
5216
5448
  ...options,
5217
5449
  functions
5218
5450
  });
5451
+ return;
5219
5452
  }
5220
5453
  const funcNames = functions?.map((f) => f.name).join(",");
5221
5454
  const attributes = {
5222
5455
  ["generate.signature"]: this.signature.toString(),
5223
5456
  ["generate.functions"]: funcNames ?? ""
5224
5457
  };
5225
- return await tracer.startActiveSpan(
5226
- "Generate",
5227
- {
5228
- kind: import_api22.SpanKind.SERVER,
5229
- attributes
5230
- },
5231
- async (span) => {
5232
- const res = this._forward(ai, values, options, span);
5233
- span.end();
5234
- return res;
5235
- }
5236
- );
5458
+ const span = tracer.startSpan("Generate", {
5459
+ kind: import_api22.SpanKind.SERVER,
5460
+ attributes
5461
+ });
5462
+ try {
5463
+ yield* this._forward2(
5464
+ ai,
5465
+ values,
5466
+ {
5467
+ ...options,
5468
+ functions
5469
+ },
5470
+ span
5471
+ );
5472
+ } finally {
5473
+ span.end();
5474
+ }
5475
+ }
5476
+ async forward(ai, values, options) {
5477
+ const generator = this._forward1(ai, values, {
5478
+ ...options
5479
+ });
5480
+ let buffer = {};
5481
+ for await (const delta of generator) {
5482
+ buffer = mergeDeltas(buffer, delta.delta);
5483
+ }
5484
+ this.trace = { ...values, ...buffer };
5485
+ return buffer;
5486
+ }
5487
+ async *streamingForward(ai, values, options) {
5488
+ yield* this._forward1(ai, values, {
5489
+ ...options,
5490
+ stream: true
5491
+ });
5237
5492
  }
5238
5493
  };
5239
5494
 
@@ -5323,7 +5578,7 @@ var AxAgent = class {
5323
5578
  func: wrappedFunc
5324
5579
  };
5325
5580
  }
5326
- async forward(ai, values, options) {
5581
+ init(ai, options) {
5327
5582
  const _ai = this.ai ?? ai;
5328
5583
  const funcs = [
5329
5584
  ...options?.functions ?? [],
@@ -5334,26 +5589,15 @@ var AxAgent = class {
5334
5589
  const opt2 = { ...options, functions: funcs };
5335
5590
  this.program = new AxGen(this.signature, opt2);
5336
5591
  }
5337
- if (!options?.tracer) {
5338
- return await this.program.forward(_ai, values, opt);
5339
- }
5340
- const attributes = {
5341
- ["agent.name"]: this.name,
5342
- ["agent.description"]: this.description,
5343
- ["agent.subAgents"]: this.subAgentList ?? "none"
5344
- };
5345
- return await options?.tracer.startActiveSpan(
5346
- "Agent",
5347
- {
5348
- kind: import_api23.SpanKind.SERVER,
5349
- attributes
5350
- },
5351
- async (span) => {
5352
- const res = await this.program.forward(_ai, values, opt);
5353
- span.end();
5354
- return res;
5355
- }
5356
- );
5592
+ return { _ai, opt };
5593
+ }
5594
+ async forward(ai, values, options) {
5595
+ const { _ai, opt } = this.init(ai, options);
5596
+ return await this.program.forward(_ai, values, opt);
5597
+ }
5598
+ async *streamingForward(ai, values, options) {
5599
+ const { _ai, opt } = this.init(ai, options);
5600
+ return yield* this.program.streamingForward(_ai, values, opt);
5357
5601
  }
5358
5602
  };
5359
5603
  function toCamelCase(inputString) {
@@ -5624,7 +5868,7 @@ var randomSample = (array, n) => {
5624
5868
  };
5625
5869
 
5626
5870
  // db/base.ts
5627
- var import_api24 = require("@opentelemetry/api");
5871
+ var import_api23 = require("@opentelemetry/api");
5628
5872
  var AxDBBase = class {
5629
5873
  name;
5630
5874
  fetch;
@@ -5651,7 +5895,7 @@ var AxDBBase = class {
5651
5895
  return await this.tracer?.startActiveSpan(
5652
5896
  "DB Upsert Request",
5653
5897
  {
5654
- kind: import_api24.SpanKind.SERVER,
5898
+ kind: import_api23.SpanKind.SERVER,
5655
5899
  attributes: {
5656
5900
  [axSpanAttributes.DB_SYSTEM]: this.name,
5657
5901
  [axSpanAttributes.DB_OPERATION_NAME]: "upsert",
@@ -5661,9 +5905,11 @@ var AxDBBase = class {
5661
5905
  }
5662
5906
  },
5663
5907
  async (span) => {
5664
- const res = await this._upsert(req, update, { span });
5665
- span.end();
5666
- return res;
5908
+ try {
5909
+ return await this._upsert(req, update, { span });
5910
+ } finally {
5911
+ span.end();
5912
+ }
5667
5913
  }
5668
5914
  );
5669
5915
  }
@@ -5683,7 +5929,7 @@ var AxDBBase = class {
5683
5929
  return await this.tracer?.startActiveSpan(
5684
5930
  "DB Batch Upsert Request",
5685
5931
  {
5686
- kind: import_api24.SpanKind.SERVER,
5932
+ kind: import_api23.SpanKind.SERVER,
5687
5933
  attributes: {
5688
5934
  [axSpanAttributes.DB_SYSTEM]: this.name,
5689
5935
  [axSpanAttributes.DB_OPERATION_NAME]: "upsert",
@@ -5693,9 +5939,11 @@ var AxDBBase = class {
5693
5939
  }
5694
5940
  },
5695
5941
  async (span) => {
5696
- const res = await this._batchUpsert(req, update, { span });
5697
- span.end();
5698
- return res;
5942
+ try {
5943
+ return await this._batchUpsert(req, update, { span });
5944
+ } finally {
5945
+ span.end();
5946
+ }
5699
5947
  }
5700
5948
  );
5701
5949
  }
@@ -5709,7 +5957,7 @@ var AxDBBase = class {
5709
5957
  return await this.tracer?.startActiveSpan(
5710
5958
  "DB Query Request",
5711
5959
  {
5712
- kind: import_api24.SpanKind.SERVER,
5960
+ kind: import_api23.SpanKind.SERVER,
5713
5961
  attributes: {
5714
5962
  [axSpanAttributes.DB_SYSTEM]: this.name,
5715
5963
  [axSpanAttributes.DB_OPERATION_NAME]: "upsert",
@@ -5719,9 +5967,11 @@ var AxDBBase = class {
5719
5967
  }
5720
5968
  },
5721
5969
  async (span) => {
5722
- const res = await this._query(req, { span });
5723
- span.end();
5724
- return res;
5970
+ try {
5971
+ return await this._query(req, { span });
5972
+ } finally {
5973
+ span.end();
5974
+ }
5725
5975
  }
5726
5976
  );
5727
5977
  }
@@ -6988,6 +7238,122 @@ var AxEmbeddingAdapter = class {
6988
7238
  }
6989
7239
  };
6990
7240
 
7241
+ // ai/mock/api.ts
7242
+ var AxMockAIService = class {
7243
+ constructor(config = {}) {
7244
+ this.config = config;
7245
+ }
7246
+ options = {};
7247
+ metrics = {
7248
+ latency: {
7249
+ chat: { mean: 0, p95: 0, p99: 0, samples: [] },
7250
+ embed: { mean: 0, p95: 0, p99: 0, samples: [] }
7251
+ },
7252
+ errors: {
7253
+ chat: { count: 0, rate: 0, total: 0 },
7254
+ embed: { count: 0, rate: 0, total: 0 }
7255
+ }
7256
+ };
7257
+ getName() {
7258
+ return this.config.name ?? "mock-ai-service";
7259
+ }
7260
+ getModelInfo() {
7261
+ return {
7262
+ name: "mock-model",
7263
+ provider: "mock-provider",
7264
+ promptTokenCostPer1M: 100,
7265
+ completionTokenCostPer1M: 100,
7266
+ ...this.config.modelInfo
7267
+ };
7268
+ }
7269
+ getEmbedModelInfo() {
7270
+ return this.config.embedModelInfo;
7271
+ }
7272
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
7273
+ getFeatures(_model) {
7274
+ return {
7275
+ functions: this.config.features?.functions ?? false,
7276
+ streaming: this.config.features?.streaming ?? false
7277
+ };
7278
+ }
7279
+ getModelMap() {
7280
+ return this.config.modelMap;
7281
+ }
7282
+ getMetrics() {
7283
+ return this.metrics;
7284
+ }
7285
+ async chat(req, _options) {
7286
+ if (this.config.latencyMs) {
7287
+ await new Promise((resolve) => setTimeout(resolve, this.config.latencyMs));
7288
+ }
7289
+ if (this.config.shouldError) {
7290
+ throw new Error(this.config.errorMessage ?? "Mock chat error");
7291
+ }
7292
+ this.updateMetrics("chat");
7293
+ if (typeof this.config.chatResponse === "function") {
7294
+ return this.config.chatResponse(req);
7295
+ }
7296
+ return this.config.chatResponse ?? {
7297
+ results: [
7298
+ {
7299
+ content: "Mock response",
7300
+ finishReason: "stop"
7301
+ }
7302
+ ],
7303
+ modelUsage: {
7304
+ promptTokens: 10,
7305
+ completionTokens: 5,
7306
+ totalTokens: 15
7307
+ }
7308
+ };
7309
+ }
7310
+ async embed(req, _options) {
7311
+ if (this.config.latencyMs) {
7312
+ await new Promise((resolve) => setTimeout(resolve, this.config.latencyMs));
7313
+ }
7314
+ if (this.config.shouldError) {
7315
+ throw new Error(this.config.errorMessage ?? "Mock embed error");
7316
+ }
7317
+ this.updateMetrics("embed");
7318
+ if (typeof this.config.embedResponse === "function") {
7319
+ return this.config.embedResponse(req);
7320
+ }
7321
+ return this.config.embedResponse ?? {
7322
+ embeddings: [[0.1, 0.2, 0.3]],
7323
+ modelUsage: {
7324
+ promptTokens: 5,
7325
+ completionTokens: 0,
7326
+ totalTokens: 5
7327
+ }
7328
+ };
7329
+ }
7330
+ setOptions(options) {
7331
+ this.options = options;
7332
+ }
7333
+ getOptions() {
7334
+ return this.options;
7335
+ }
7336
+ updateMetrics(type) {
7337
+ const latency = this.config.latencyMs ?? 0;
7338
+ this.metrics.latency[type].samples.push(latency);
7339
+ const samples = this.metrics.latency[type].samples;
7340
+ this.metrics.latency[type].mean = samples.reduce((a, b) => a + b, 0) / samples.length;
7341
+ if (samples.length > 0) {
7342
+ const sortedSamples = [...samples].sort((a, b) => a - b);
7343
+ const p95Index = Math.max(0, Math.floor(sortedSamples.length * 0.95) - 1);
7344
+ this.metrics.latency[type].p95 = sortedSamples[p95Index] ?? latency;
7345
+ const p99Index = Math.max(0, Math.floor(sortedSamples.length * 0.99) - 1);
7346
+ this.metrics.latency[type].p99 = sortedSamples[p99Index] ?? latency;
7347
+ }
7348
+ if (this.config.shouldError) {
7349
+ this.metrics.errors[type].count++;
7350
+ this.metrics.errors[type].total++;
7351
+ const totalRequests = this.metrics.latency[type].samples.length;
7352
+ this.metrics.errors[type].rate = totalRequests > 0 ? this.metrics.errors[type].count / totalRequests : 0;
7353
+ }
7354
+ }
7355
+ };
7356
+
6991
7357
  // prompts/rag.ts
6992
7358
  var AxRAG = class extends AxChainOfThought {
6993
7359
  genQuery;
@@ -7077,6 +7443,7 @@ var AxRAG = class extends AxChainOfThought {
7077
7443
  AxJSInterpreterPermission,
7078
7444
  AxLLMRequestTypeValues,
7079
7445
  AxMemory,
7446
+ AxMockAIService,
7080
7447
  AxProgram,
7081
7448
  AxProgramWithSignature,
7082
7449
  AxPromptTemplate,