@ax-llm/ax 10.0.39 → 10.0.41

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
@@ -33,6 +33,7 @@ __export(index_exports, {
33
33
  AxAI: () => AxAI,
34
34
  AxAIAnthropic: () => AxAIAnthropic,
35
35
  AxAIAnthropicModel: () => AxAIAnthropicModel,
36
+ AxAIAnthropicVertexModel: () => AxAIAnthropicVertexModel,
36
37
  AxAIAzureOpenAI: () => AxAIAzureOpenAI,
37
38
  AxAICohere: () => AxAICohere,
38
39
  AxAICohereEmbedModel: () => AxAICohereEmbedModel,
@@ -84,6 +85,7 @@ __export(index_exports, {
84
85
  AxJSInterpreterPermission: () => AxJSInterpreterPermission,
85
86
  AxLLMRequestTypeValues: () => AxLLMRequestTypeValues,
86
87
  AxMemory: () => AxMemory,
88
+ AxMockAIService: () => AxMockAIService,
87
89
  AxProgram: () => AxProgram,
88
90
  AxProgramWithSignature: () => AxProgramWithSignature,
89
91
  AxPromptTemplate: () => AxPromptTemplate,
@@ -618,9 +620,11 @@ var AxBaseAI = class {
618
620
  }
619
621
  },
620
622
  async (span) => {
621
- const res = await this._chat2(model, modelConfig, req, options, span);
622
- span.end();
623
- return res;
623
+ try {
624
+ return await this._chat2(model, modelConfig, req, options, span);
625
+ } finally {
626
+ span.end();
627
+ }
624
628
  }
625
629
  );
626
630
  }
@@ -743,9 +747,11 @@ var AxBaseAI = class {
743
747
  }
744
748
  },
745
749
  async (span) => {
746
- const res = await this._embed2(embedModel, req, options, span);
747
- span.end();
748
- return res;
750
+ try {
751
+ return await this._embed2(embedModel, req, options, span);
752
+ } finally {
753
+ span.end();
754
+ }
749
755
  }
750
756
  );
751
757
  }
@@ -813,7 +819,7 @@ ${colorLog.whiteBright(msg.content)}`;
813
819
  const items2 = msg.content.map((v) => {
814
820
  switch (v.type) {
815
821
  case "text":
816
- return `(Text) ${colorLog.whiteBright(v.text)}`;
822
+ return `${colorLog.whiteBright(v.text)}`;
817
823
  case "image":
818
824
  return `(Image, ${v.mimeType}) ${colorLog.whiteBright(v.image.substring(0, 10))}`;
819
825
  default:
@@ -878,6 +884,61 @@ var setResponseAttr = (res, span) => {
878
884
  }
879
885
  };
880
886
 
887
+ // ai/google-vertex/auth.ts
888
+ var import_google_auth_library = require("google-auth-library");
889
+ var GoogleVertexAuth = class {
890
+ auth;
891
+ client;
892
+ currentToken;
893
+ tokenExpiry;
894
+ constructor(config = {}) {
895
+ this.auth = new import_google_auth_library.GoogleAuth({
896
+ scopes: ["https://www.googleapis.com/auth/cloud-platform"],
897
+ ...config
898
+ });
899
+ }
900
+ async getAuthenticatedClient() {
901
+ if (!this.client) {
902
+ this.client = await this.auth.getClient();
903
+ }
904
+ return this.client;
905
+ }
906
+ async getAccessToken() {
907
+ if (this.currentToken && this.tokenExpiry && Date.now() < this.tokenExpiry) {
908
+ return this.currentToken;
909
+ }
910
+ const client = await this.getAuthenticatedClient();
911
+ const tokenResponse = await client.getAccessToken();
912
+ this.currentToken = tokenResponse.token ?? void 0;
913
+ const expiry = this.getExpiry(tokenResponse);
914
+ const fiveMinutes = 5 * 60 * 1e3;
915
+ this.tokenExpiry = expiry - fiveMinutes;
916
+ return this.currentToken;
917
+ }
918
+ /**
919
+ * Get the expiry date from the token response.
920
+ */
921
+ getExpiry(tokenResponse) {
922
+ const oneHour = 3600 * 1e3;
923
+ let expiry = Date.now() + oneHour;
924
+ let responseExpiry = tokenResponse.res?.data?.expiry_date;
925
+ if (responseExpiry) {
926
+ if (typeof responseExpiry === "number") {
927
+ expiry = responseExpiry;
928
+ } else if (responseExpiry instanceof Date) {
929
+ expiry = responseExpiry.getTime();
930
+ } else if (typeof responseExpiry === "string") {
931
+ expiry = new Date(responseExpiry).getTime();
932
+ } else {
933
+ console.warn("Unknown expiry type", responseExpiry);
934
+ }
935
+ } else {
936
+ console.warn("No expiry date found in response", tokenResponse.res?.data);
937
+ }
938
+ return expiry;
939
+ }
940
+ };
941
+
881
942
  // ai/anthropic/types.ts
882
943
  var AxAIAnthropicModel = /* @__PURE__ */ ((AxAIAnthropicModel2) => {
883
944
  AxAIAnthropicModel2["Claude35Sonnet"] = "claude-3-5-sonnet-latest";
@@ -889,6 +950,14 @@ var AxAIAnthropicModel = /* @__PURE__ */ ((AxAIAnthropicModel2) => {
889
950
  AxAIAnthropicModel2["ClaudeInstant12"] = "claude-instant-1.2";
890
951
  return AxAIAnthropicModel2;
891
952
  })(AxAIAnthropicModel || {});
953
+ var AxAIAnthropicVertexModel = /* @__PURE__ */ ((AxAIAnthropicVertexModel2) => {
954
+ AxAIAnthropicVertexModel2["Claude35Haiku"] = "claude-3-5-haiku";
955
+ AxAIAnthropicVertexModel2["Claude35Sonnet"] = "claude-3-5-sonnet";
956
+ AxAIAnthropicVertexModel2["Claude35SonnetV2"] = "claude-3-5-sonnet-v2";
957
+ AxAIAnthropicVertexModel2["Claude3Haiku"] = "claude-3-haiku";
958
+ AxAIAnthropicVertexModel2["Claude3Opus"] = "claude-3-opus";
959
+ return AxAIAnthropicVertexModel2;
960
+ })(AxAIAnthropicVertexModel || {});
892
961
 
893
962
  // ai/anthropic/info.ts
894
963
  var axModelInfoAnthropic = [
@@ -945,8 +1014,9 @@ var axAIAnthropicDefaultConfig = () => structuredClone({
945
1014
  ...axBaseAIDefaultConfig()
946
1015
  });
947
1016
  var AxAIAnthropicImpl = class {
948
- constructor(config) {
1017
+ constructor(config, isVertex) {
949
1018
  this.config = config;
1019
+ this.isVertex = isVertex;
950
1020
  }
951
1021
  getModelConfig() {
952
1022
  const { config } = this;
@@ -965,9 +1035,41 @@ var AxAIAnthropicImpl = class {
965
1035
  }
966
1036
  createChatReq = (req) => {
967
1037
  const model = req.model;
968
- const apiConfig = {
969
- name: "/messages"
970
- };
1038
+ const stream = req.modelConfig?.stream ?? this.config.stream;
1039
+ let apiConfig;
1040
+ if (this.isVertex) {
1041
+ apiConfig = {
1042
+ name: stream ? `/models/${model}:streamRawPredict?alt=sse` : `/models/${model}:rawPredict`
1043
+ };
1044
+ } else {
1045
+ apiConfig = {
1046
+ name: "/messages"
1047
+ };
1048
+ }
1049
+ let toolsChoice;
1050
+ if (req.functionCall && req.functions && req.functions.length > 0) {
1051
+ if (typeof req.functionCall === "string") {
1052
+ switch (req.functionCall) {
1053
+ case "auto":
1054
+ toolsChoice = { tool_choice: { type: "auto" } };
1055
+ break;
1056
+ case "required":
1057
+ toolsChoice = { tool_choice: { type: "any" } };
1058
+ break;
1059
+ case "none":
1060
+ throw new Error("functionCall none not supported");
1061
+ }
1062
+ } else if ("function" in req.functionCall) {
1063
+ toolsChoice = {
1064
+ tool_choice: {
1065
+ type: "tool",
1066
+ name: req.functionCall.function.name
1067
+ }
1068
+ };
1069
+ } else {
1070
+ throw new Error("Invalid function call type, must be string or object");
1071
+ }
1072
+ }
971
1073
  const system = req.chatPrompt.filter((msg) => msg.role === "system").map((msg) => ({
972
1074
  type: "text",
973
1075
  text: msg.content,
@@ -982,15 +1084,15 @@ var AxAIAnthropicImpl = class {
982
1084
  input_schema: v.parameters
983
1085
  })
984
1086
  );
985
- const stream = req.modelConfig?.stream ?? this.config.stream;
986
1087
  const reqValue = {
987
- model,
1088
+ ...this.isVertex ? { anthropic_version: "vertex-2023-10-16" } : { model },
988
1089
  max_tokens: req.modelConfig?.maxTokens ?? this.config.maxTokens,
989
1090
  stop_sequences: req.modelConfig?.stopSequences ?? this.config.stopSequences,
990
1091
  temperature: req.modelConfig?.temperature ?? this.config.temperature,
991
1092
  top_p: req.modelConfig?.topP ?? this.config.topP,
992
1093
  top_k: req.modelConfig?.topK ?? this.config.topK,
993
- ...tools && tools.length > 0 ? { tools, tool_choice: { type: "auto" } } : {},
1094
+ ...toolsChoice,
1095
+ ...tools && tools.length > 0 ? { tools } : {},
994
1096
  ...stream ? { stream: true } : {},
995
1097
  ...system ? { system } : {},
996
1098
  messages
@@ -1138,26 +1240,45 @@ var AxAIAnthropicImpl = class {
1138
1240
  var AxAIAnthropic = class extends AxBaseAI {
1139
1241
  constructor({
1140
1242
  apiKey,
1243
+ projectId,
1244
+ region,
1141
1245
  config,
1142
1246
  options,
1143
1247
  modelMap
1144
1248
  }) {
1145
- if (!apiKey || apiKey === "") {
1146
- throw new Error("Anthropic API key not set");
1249
+ const isVertex = projectId !== void 0 && region !== void 0;
1250
+ let apiURL;
1251
+ let headers;
1252
+ if (isVertex) {
1253
+ apiURL = `https://${region}-aiplatform.googleapis.com/v1/projects/${projectId}/locations/${region}/publishers/anthropic/`;
1254
+ if (apiKey) {
1255
+ headers = async () => ({ Authorization: `Bearer ${apiKey}` });
1256
+ } else {
1257
+ const vertexAuth = new GoogleVertexAuth();
1258
+ headers = async () => ({
1259
+ Authorization: `Bearer ${await vertexAuth.getAccessToken()}`
1260
+ });
1261
+ }
1262
+ } else {
1263
+ if (!apiKey) {
1264
+ throw new Error("Anthropic API key not set");
1265
+ }
1266
+ apiURL = "https://api.anthropic.com/v1";
1267
+ headers = async () => ({
1268
+ "anthropic-version": "2023-06-01",
1269
+ "anthropic-beta": "prompt-caching-2024-07-31",
1270
+ "x-api-key": apiKey
1271
+ });
1147
1272
  }
1148
1273
  const _config = {
1149
1274
  ...axAIAnthropicDefaultConfig(),
1150
1275
  ...config
1151
1276
  };
1152
- const aiImpl = new AxAIAnthropicImpl(_config);
1277
+ const aiImpl = new AxAIAnthropicImpl(_config, isVertex);
1153
1278
  super(aiImpl, {
1154
1279
  name: "Anthropic",
1155
- apiURL: "https://api.anthropic.com/v1",
1156
- headers: async () => ({
1157
- "anthropic-version": "2023-06-01",
1158
- "anthropic-beta": "prompt-caching-2024-07-31",
1159
- "x-api-key": apiKey
1160
- }),
1280
+ apiURL,
1281
+ headers,
1161
1282
  modelInfo: axModelInfoAnthropic,
1162
1283
  models: { model: _config.model },
1163
1284
  options,
@@ -2094,61 +2215,6 @@ var AxAIDeepSeek = class extends AxAIOpenAI {
2094
2215
  }
2095
2216
  };
2096
2217
 
2097
- // ai/google-gemini/auth.ts
2098
- var import_google_auth_library = require("google-auth-library");
2099
- var GoogleVertexAuth = class {
2100
- auth;
2101
- client;
2102
- currentToken;
2103
- tokenExpiry;
2104
- constructor(config = {}) {
2105
- this.auth = new import_google_auth_library.GoogleAuth({
2106
- scopes: ["https://www.googleapis.com/auth/cloud-platform"],
2107
- ...config
2108
- });
2109
- }
2110
- async getAuthenticatedClient() {
2111
- if (!this.client) {
2112
- this.client = await this.auth.getClient();
2113
- }
2114
- return this.client;
2115
- }
2116
- async getAccessToken() {
2117
- if (this.currentToken && this.tokenExpiry && Date.now() < this.tokenExpiry) {
2118
- return this.currentToken;
2119
- }
2120
- const client = await this.getAuthenticatedClient();
2121
- const tokenResponse = await client.getAccessToken();
2122
- this.currentToken = tokenResponse.token ?? void 0;
2123
- const expiry = this.getExpiry(tokenResponse);
2124
- const fiveMinutes = 5 * 60 * 1e3;
2125
- this.tokenExpiry = expiry - fiveMinutes;
2126
- return this.currentToken;
2127
- }
2128
- /**
2129
- * Get the expiry date from the token response.
2130
- */
2131
- getExpiry(tokenResponse) {
2132
- const oneHour = 3600 * 1e3;
2133
- let expiry = Date.now() + oneHour;
2134
- let responseExpiry = tokenResponse.res?.data?.expiry_date;
2135
- if (responseExpiry) {
2136
- if (typeof responseExpiry === "number") {
2137
- expiry = responseExpiry;
2138
- } else if (responseExpiry instanceof Date) {
2139
- expiry = responseExpiry.getTime();
2140
- } else if (typeof responseExpiry === "string") {
2141
- expiry = new Date(responseExpiry).getTime();
2142
- } else {
2143
- console.warn("Unknown expiry type", responseExpiry);
2144
- }
2145
- } else {
2146
- console.warn("No expiry date found in response", tokenResponse.res?.data);
2147
- }
2148
- return expiry;
2149
- }
2150
- };
2151
-
2152
2218
  // ai/google-gemini/types.ts
2153
2219
  var AxAIGoogleGeminiModel = /* @__PURE__ */ ((AxAIGoogleGeminiModel2) => {
2154
2220
  AxAIGoogleGeminiModel2["Gemini1Pro"] = "gemini-1.0-pro";
@@ -2238,11 +2304,10 @@ var axAIGoogleGeminiDefaultConfig = () => structuredClone({
2238
2304
  ...axBaseAIDefaultConfig()
2239
2305
  });
2240
2306
  var AxAIGoogleGeminiImpl = class {
2241
- constructor(config, isVertex, apiKey, keyFile, options) {
2307
+ constructor(config, isVertex, apiKey, options) {
2242
2308
  this.config = config;
2243
2309
  this.isVertex = isVertex;
2244
2310
  this.apiKey = apiKey;
2245
- this.keyFile = keyFile;
2246
2311
  this.options = options;
2247
2312
  }
2248
2313
  getModelConfig() {
@@ -2519,7 +2584,6 @@ var AxAIGoogleGemini = class extends AxBaseAI {
2519
2584
  apiKey,
2520
2585
  projectId,
2521
2586
  region,
2522
- keyFile,
2523
2587
  config,
2524
2588
  options,
2525
2589
  modelMap
@@ -2532,9 +2596,7 @@ var AxAIGoogleGemini = class extends AxBaseAI {
2532
2596
  if (apiKey) {
2533
2597
  headers = async () => ({ Authorization: `Bearer ${apiKey}` });
2534
2598
  } else {
2535
- const vertexAuth = new GoogleVertexAuth({
2536
- keyFile
2537
- });
2599
+ const vertexAuth = new GoogleVertexAuth();
2538
2600
  headers = async () => ({
2539
2601
  Authorization: `Bearer ${await vertexAuth.getAccessToken()}`
2540
2602
  });
@@ -2550,13 +2612,7 @@ var AxAIGoogleGemini = class extends AxBaseAI {
2550
2612
  ...axAIGoogleGeminiDefaultConfig(),
2551
2613
  ...config
2552
2614
  };
2553
- const aiImpl = new AxAIGoogleGeminiImpl(
2554
- _config,
2555
- isVertex,
2556
- apiKey,
2557
- keyFile,
2558
- options
2559
- );
2615
+ const aiImpl = new AxAIGoogleGeminiImpl(_config, isVertex, apiKey, options);
2560
2616
  super(aiImpl, {
2561
2617
  name: "GoogleGeminiAI",
2562
2618
  apiURL,
@@ -3299,9 +3355,6 @@ var AxAI = class {
3299
3355
  }
3300
3356
  };
3301
3357
 
3302
- // prompts/agent.ts
3303
- var import_api23 = require("@opentelemetry/api");
3304
-
3305
3358
  // dsp/generate.ts
3306
3359
  var import_web5 = require("stream/web");
3307
3360
  var import_api22 = require("@opentelemetry/api");
@@ -3490,7 +3543,7 @@ var AxAssertionError = class extends Error {
3490
3543
  extraFields.push({
3491
3544
  name: "error",
3492
3545
  title: "Error In Output",
3493
- description: this.message
3546
+ description: `You must follow the following instructions, "${this.message}".`
3494
3547
  });
3495
3548
  return extraFields;
3496
3549
  };
@@ -3529,18 +3582,6 @@ var assertStreamingAssertions = (asserts, values, xstate, content, final) => {
3529
3582
  }
3530
3583
  }
3531
3584
  };
3532
- var assertRequiredFields = (sig, values) => {
3533
- const fields = sig.getOutputFields();
3534
- const missingFields = fields.filter(
3535
- (f) => !f.isOptional && !(f.name in values)
3536
- );
3537
- if (missingFields.length > 0) {
3538
- throw new AxAssertionError({
3539
- message: `Output must include: ${missingFields.map((f) => `\`${f.title}:\``).join(", ")}`,
3540
- values
3541
- });
3542
- }
3543
- };
3544
3585
 
3545
3586
  // dsp/extract.ts
3546
3587
  var import_json5 = __toESM(require("json5"), 1);
@@ -4088,6 +4129,67 @@ var parseMarkdownList = (input) => {
4088
4129
  }
4089
4130
  return list;
4090
4131
  };
4132
+ function mergeDeltas(base, delta) {
4133
+ for (const key of Object.keys(delta)) {
4134
+ const baseValue = base[key];
4135
+ const deltaValue = delta[key];
4136
+ if ((baseValue === void 0 || Array.isArray(baseValue)) && Array.isArray(deltaValue)) {
4137
+ base[key] = [...baseValue ?? [], ...deltaValue];
4138
+ } else if ((baseValue === void 0 || typeof baseValue === "string") && typeof deltaValue === "string") {
4139
+ base[key] = (baseValue ?? "") + deltaValue;
4140
+ } else {
4141
+ base[key] = deltaValue;
4142
+ }
4143
+ }
4144
+ return base;
4145
+ }
4146
+ var LRUCache = class {
4147
+ cache = /* @__PURE__ */ new Map();
4148
+ maxSize;
4149
+ constructor(maxSize) {
4150
+ this.maxSize = maxSize;
4151
+ }
4152
+ get(key) {
4153
+ const value = this.cache.get(key);
4154
+ if (value) {
4155
+ this.cache.delete(key);
4156
+ this.cache.set(key, value);
4157
+ }
4158
+ return value;
4159
+ }
4160
+ set(key, value) {
4161
+ if (this.cache.has(key)) {
4162
+ this.cache.delete(key);
4163
+ } else if (this.cache.size >= this.maxSize) {
4164
+ const firstKey = this.cache.keys().next().value;
4165
+ if (firstKey) {
4166
+ this.cache.delete(firstKey);
4167
+ }
4168
+ }
4169
+ this.cache.set(key, value);
4170
+ }
4171
+ };
4172
+ var globalPrefixCache = new LRUCache(500);
4173
+ function matchesContent(content, prefix, startIndex = 0, prefixCache = globalPrefixCache) {
4174
+ const exactMatchIndex = content.indexOf(prefix, startIndex);
4175
+ if (exactMatchIndex !== -1) {
4176
+ return exactMatchIndex;
4177
+ }
4178
+ const prefixes = prefixCache.get(prefix) ?? Array.from({ length: prefix.length }, (_, i) => prefix.slice(0, i + 1));
4179
+ if (!prefixCache.get(prefix)) {
4180
+ prefixCache.set(prefix, prefixes);
4181
+ }
4182
+ const contentEnd = content.slice(
4183
+ Math.max(startIndex, content.length - prefix.length)
4184
+ );
4185
+ for (let i = 0; i < prefixes.length - 1; i++) {
4186
+ const partialPrefix = prefixes[i];
4187
+ if (contentEnd.endsWith(partialPrefix)) {
4188
+ return -2;
4189
+ }
4190
+ }
4191
+ return -1;
4192
+ }
4091
4193
 
4092
4194
  // dsp/program.ts
4093
4195
  var AxProgramWithSignature = class {
@@ -4120,6 +4222,9 @@ var AxProgramWithSignature = class {
4120
4222
  async forward(_ai, _values, _options) {
4121
4223
  throw new Error("forward() not implemented");
4122
4224
  }
4225
+ async *streamingForward(_ai, _values, _options) {
4226
+ throw new Error("streamingForward() not implemented");
4227
+ }
4123
4228
  setId(id) {
4124
4229
  this.key = { id, custom: true };
4125
4230
  for (const child of this.children) {
@@ -4214,6 +4319,9 @@ var AxProgram = class {
4214
4319
  async forward(_ai, _values, _options) {
4215
4320
  throw new Error("forward() not implemented");
4216
4321
  }
4322
+ async *streamingForward(_ai, _values, _options) {
4323
+ throw new Error("streamingForward() not implemented");
4324
+ }
4217
4325
  setId(id) {
4218
4326
  this.key = { id, custom: true };
4219
4327
  for (const child of this.children) {
@@ -4311,9 +4419,10 @@ ${outputFields}`);
4311
4419
  task.push(formattingRules.trim());
4312
4420
  const desc = this.sig.getDescription();
4313
4421
  if (desc) {
4422
+ const capitalized = capitalizeFirstLetter(desc.trim());
4314
4423
  task.push(
4315
4424
  `## TASK DESCRIPTION
4316
- ${capitalizeFirstLetter(desc.endsWith(".") ? desc : desc + ".")}`
4425
+ ${capitalized.endsWith(".") ? capitalized : capitalized + "."}`
4317
4426
  );
4318
4427
  }
4319
4428
  this.task = {
@@ -4361,16 +4470,42 @@ ${capitalizeFirstLetter(desc.endsWith(".") ? desc : desc + ".")}`
4361
4470
  };
4362
4471
  renderExtraFields = (extraFields) => {
4363
4472
  const prompt = [];
4364
- if (extraFields && extraFields.length > 0) {
4365
- extraFields.forEach((field) => {
4366
- const fn = this.fieldTemplates?.[field.name] ?? this.defaultRenderInField;
4367
- prompt.push(...fn(field, field.description));
4368
- });
4369
- }
4370
- if (prompt.every((v) => v.type === "text")) {
4371
- return prompt.map((v) => v.text).join("\n\n");
4372
- }
4373
- return prompt.reduce(combineConsecutiveStrings("\n"), []);
4473
+ if (!extraFields || extraFields.length === 0) {
4474
+ return prompt;
4475
+ }
4476
+ const groupedFields = extraFields.reduce(
4477
+ (acc, field) => {
4478
+ const title = field.title;
4479
+ if (!acc[title]) {
4480
+ acc[title] = [];
4481
+ }
4482
+ acc[title].push(field);
4483
+ return acc;
4484
+ },
4485
+ {}
4486
+ );
4487
+ const formattedGroupedFields = Object.entries(groupedFields).map(([title, fields]) => {
4488
+ if (fields.length === 1) {
4489
+ const field = fields[0];
4490
+ return {
4491
+ title,
4492
+ name: field.name,
4493
+ description: field.description
4494
+ };
4495
+ } else if (fields.length > 1) {
4496
+ const valuesList = fields.map((field) => `- ${field.description}`).join("\n");
4497
+ return {
4498
+ title,
4499
+ name: fields[0].name,
4500
+ description: valuesList
4501
+ };
4502
+ }
4503
+ }).filter(Boolean);
4504
+ formattedGroupedFields.forEach((field) => {
4505
+ const fn = this.fieldTemplates?.[field.name] ?? this.defaultRenderInField;
4506
+ prompt.push(...fn(field, field.description));
4507
+ });
4508
+ return prompt;
4374
4509
  };
4375
4510
  renderExamples = (data) => {
4376
4511
  const list = [];
@@ -4619,34 +4754,44 @@ function capitalizeFirstLetter(str) {
4619
4754
  }
4620
4755
 
4621
4756
  // dsp/validate.ts
4757
+ var colorLog4 = new ColorLog();
4622
4758
  var ValidationError = class extends Error {
4623
- field;
4624
- value;
4759
+ fields;
4625
4760
  constructor({
4626
4761
  message,
4627
- field,
4628
- value
4762
+ fields
4629
4763
  }) {
4630
4764
  super(message);
4631
- this.field = field;
4632
- this.value = value;
4765
+ this.fields = fields;
4633
4766
  this.name = this.constructor.name;
4634
4767
  Error.captureStackTrace(this, this.constructor);
4635
4768
  }
4636
- getField = () => this.field;
4637
- getValue = () => this.value;
4769
+ getFields = () => this.fields;
4638
4770
  getFixingInstructions = () => {
4639
- const f = this.field;
4640
- const extraFields = [
4641
- {
4642
- name: `outputError`,
4643
- title: `Invalid Output Field`,
4644
- description: `Invalid format for field \`${f.title}\` of type \`${toFieldType(f.type)}\`, format should match: \`${f.description}\``
4645
- }
4646
- ];
4647
- return extraFields;
4771
+ return this.fields.map((field) => ({
4772
+ name: "outputError",
4773
+ title: "Error In Output",
4774
+ description: `Please fix and return the field \`${field.title}\` of type \`${toFieldType(field.type)}\`, ${this.message}.`
4775
+ }));
4648
4776
  };
4649
4777
  };
4778
+ function handleValidationError(mem, errorFields, ai, promptTemplate, sessionId) {
4779
+ mem.add(
4780
+ {
4781
+ role: "user",
4782
+ content: promptTemplate.renderExtraFields(errorFields)
4783
+ },
4784
+ sessionId
4785
+ );
4786
+ mem.addTag("error");
4787
+ if (ai.getOptions().debug) {
4788
+ const errors = errorFields.map((field) => `- ${field.title}: ${field.description}`).join("\n");
4789
+ process.stdout.write(colorLog4.red(`
4790
+ Error Correction:
4791
+ ${errors}
4792
+ `));
4793
+ }
4794
+ }
4650
4795
 
4651
4796
  // dsp/datetime.ts
4652
4797
  function parseLLMFriendlyDate(field, dateStr) {
@@ -4654,7 +4799,7 @@ function parseLLMFriendlyDate(field, dateStr) {
4654
4799
  return _parseLLMFriendlyDate(dateStr);
4655
4800
  } catch (err) {
4656
4801
  const message = err.message;
4657
- throw new ValidationError({ field, message, value: dateStr });
4802
+ throw new ValidationError({ fields: [field], message, value: dateStr });
4658
4803
  }
4659
4804
  }
4660
4805
  function _parseLLMFriendlyDate(dateStr) {
@@ -4671,7 +4816,7 @@ function parseLLMFriendlyDateTime(field, dateStr) {
4671
4816
  return _parseLLMFriendlyDateTime(dateStr);
4672
4817
  } catch (err) {
4673
4818
  const message = err.message;
4674
- throw new ValidationError({ field, message, value: dateStr });
4819
+ throw new ValidationError({ fields: [field], message, value: dateStr });
4675
4820
  }
4676
4821
  }
4677
4822
  function _parseLLMFriendlyDateTime(dateTimeStr) {
@@ -4713,41 +4858,73 @@ var formatDateWithTimezone = (date) => {
4713
4858
 
4714
4859
  // dsp/extract.ts
4715
4860
  var extractValues = (sig, values, content) => {
4716
- const xstate = { s: -1 };
4861
+ const xstate = { extractedFields: [], s: -1 };
4717
4862
  streamingExtractValues(sig, values, xstate, content);
4718
- streamingExtractFinalValue(values, xstate, content);
4863
+ streamingExtractFinalValue(sig, values, xstate, content);
4719
4864
  };
4720
- var streamingExtractValues = (sig, values, state, content) => {
4865
+ var checkMissingRequiredFields = (xstate, values, currentIndex) => {
4866
+ const missingFields = [];
4867
+ for (let i = 0; i < currentIndex; i++) {
4868
+ const field = xstate.extractedFields[i];
4869
+ if (field && !field.isOptional && values[field.name] === void 0) {
4870
+ missingFields.push(field);
4871
+ }
4872
+ }
4873
+ if (missingFields.length > 0) {
4874
+ throw new ValidationError({
4875
+ message: `Required ${missingFields.length === 1 ? "field" : "fields"} not found`,
4876
+ fields: missingFields
4877
+ });
4878
+ }
4879
+ };
4880
+ var streamingExtractValues = (sig, values, xstate, content) => {
4881
+ if (content.endsWith("\n")) {
4882
+ return true;
4883
+ }
4721
4884
  const fields = sig.getOutputFields();
4722
- for (const field of fields) {
4885
+ for (const [index, field] of fields.entries()) {
4723
4886
  if (field.name in values) {
4724
4887
  continue;
4725
4888
  }
4726
4889
  const prefix = field.title + ":";
4727
- const e = content.indexOf(prefix, state.s + 1);
4728
- if (e === -1) {
4729
- continue;
4890
+ let e = matchesContent(content, prefix, xstate.s + 1);
4891
+ switch (e) {
4892
+ case -1:
4893
+ continue;
4894
+ // Field is not found, continue to the next field
4895
+ case -2:
4896
+ return true;
4730
4897
  }
4731
- if (state.currField) {
4732
- const val = content.substring(state.s, e).trim().replace(/---+$/, "").trim();
4733
- values[state.currField.name] = validateAndParseFieldValue(
4734
- state.currField,
4735
- val
4736
- );
4898
+ let prefixLen = prefix.length;
4899
+ if (e - 1 >= 0 && content[e - 1] === "\n") {
4900
+ e -= 1;
4901
+ prefixLen += 1;
4902
+ }
4903
+ if (xstate.currField) {
4904
+ const val = content.substring(xstate.s, e).trim();
4905
+ const parsedValue = validateAndParseFieldValue(xstate.currField, val);
4906
+ if (parsedValue !== void 0) {
4907
+ values[xstate.currField.name] = parsedValue;
4908
+ }
4909
+ }
4910
+ checkMissingRequiredFields(xstate, values, index);
4911
+ xstate.s = e + prefixLen;
4912
+ xstate.currField = field;
4913
+ if (!xstate.extractedFields.includes(field)) {
4914
+ xstate.extractedFields.push(field);
4737
4915
  }
4738
- state.s = e + prefix.length;
4739
- state.currField = field;
4740
4916
  }
4741
4917
  };
4742
- var streamingExtractFinalValue = (values, state, content) => {
4743
- if (!state.currField) {
4744
- return;
4918
+ var streamingExtractFinalValue = (sig, values, xstate, content) => {
4919
+ if (xstate.currField) {
4920
+ const val = content.substring(xstate.s).trim();
4921
+ const parsedValue = validateAndParseFieldValue(xstate.currField, val);
4922
+ if (parsedValue !== void 0) {
4923
+ values[xstate.currField.name] = parsedValue;
4924
+ }
4745
4925
  }
4746
- const val = content.substring(state.s).trim().replace(/---+$/, "").trim();
4747
- values[state.currField.name] = validateAndParseFieldValue(
4748
- state.currField,
4749
- val
4750
- );
4926
+ const fields = sig.getOutputFields();
4927
+ checkMissingRequiredFields(xstate, values, fields.length - 1);
4751
4928
  };
4752
4929
  var convertValueToType = (field, val) => {
4753
4930
  switch (field.type?.name) {
@@ -4761,6 +4938,9 @@ var convertValueToType = (field, val) => {
4761
4938
  return v;
4762
4939
  }
4763
4940
  case "boolean": {
4941
+ if (typeof val === "boolean") {
4942
+ return val;
4943
+ }
4764
4944
  const v = val.toLowerCase();
4765
4945
  if (v === "true") {
4766
4946
  return true;
@@ -4775,37 +4955,73 @@ var convertValueToType = (field, val) => {
4775
4955
  case "datetime":
4776
4956
  return parseLLMFriendlyDateTime(field, val);
4777
4957
  case "class":
4778
- if (field.type.classes && !field.type.classes.includes(val)) {
4958
+ const className = val;
4959
+ if (field.type.classes && !field.type.classes.includes(className)) {
4779
4960
  throw new Error(
4780
4961
  `Invalid class '${val}', expected one of the following: ${field.type.classes.join(", ")}`
4781
4962
  );
4782
4963
  }
4783
- return val;
4964
+ return className;
4784
4965
  default:
4785
4966
  return val;
4786
4967
  }
4787
4968
  };
4788
- var expectedTypeError = (field, err, value = "") => {
4789
- const exp = field.type?.isArray ? `array of ${field.type.name}` : field.type?.name;
4790
- const message = `Error '${err.message}', expected '${exp}' got '${value}'`;
4791
- return new ValidationError({ message, field, value });
4792
- };
4969
+ function* streamValues(sig, values, xstate, content) {
4970
+ if (!xstate.currField) {
4971
+ return;
4972
+ }
4973
+ const fieldName = xstate.currField.name;
4974
+ if (!xstate.streamedIndex) {
4975
+ xstate.streamedIndex = { [fieldName]: 0 };
4976
+ }
4977
+ if (!xstate.currField.type || !xstate.currField.type.isArray && xstate.currField.type.name === "string") {
4978
+ const pos = xstate.streamedIndex[fieldName] ?? 0;
4979
+ const s = xstate.s + pos;
4980
+ const v = content.substring(s);
4981
+ yield { [fieldName]: pos === 0 ? v.trimStart() : v };
4982
+ xstate.streamedIndex[fieldName] = pos + v.length;
4983
+ return;
4984
+ }
4985
+ for (const key of Object.keys(values)) {
4986
+ const value = values[key];
4987
+ if (Array.isArray(value)) {
4988
+ const s = xstate.streamedIndex[key] ?? 0;
4989
+ const v = value.slice(s);
4990
+ if (v) {
4991
+ yield { [key]: v };
4992
+ xstate.streamedIndex[key] = s + 1;
4993
+ }
4994
+ continue;
4995
+ }
4996
+ if (!xstate.streamedIndex[key]) {
4997
+ yield { [key]: value };
4998
+ xstate.streamedIndex[key] = 1;
4999
+ }
5000
+ }
5001
+ }
4793
5002
  function validateAndParseFieldValue(field, fieldValue) {
4794
- const fv = fieldValue?.toLocaleLowerCase();
4795
- if (!fieldValue || !fv || fv === "" || fv === "null" || fv === "undefined") {
5003
+ if (!fieldValue || fieldValue === "" || fieldValue === "null" || fieldValue === "NULL" || fieldValue === "undefined") {
4796
5004
  if (field.isOptional) {
4797
5005
  return;
4798
5006
  }
4799
- throw expectedTypeError(field, new Error("Empty value"), fieldValue);
5007
+ throw new ValidationError({
5008
+ message: "Required field is missing",
5009
+ fields: [field],
5010
+ value: fieldValue
5011
+ });
4800
5012
  }
4801
- let value = fieldValue;
5013
+ let value;
4802
5014
  if (field.type?.name === "json") {
4803
5015
  try {
4804
5016
  const text = extractBlock(fieldValue);
4805
5017
  value = import_json5.default.parse(text);
4806
5018
  return value;
4807
5019
  } catch (e) {
4808
- throw expectedTypeError(field, e, fieldValue);
5020
+ throw new ValidationError({
5021
+ message: "Invalid JSON: " + e.message,
5022
+ fields: [field],
5023
+ value: fieldValue
5024
+ });
4809
5025
  }
4810
5026
  }
4811
5027
  if (field.type?.isArray) {
@@ -4819,23 +5035,33 @@ function validateAndParseFieldValue(field, fieldValue) {
4819
5035
  throw new Error("Expected an array");
4820
5036
  }
4821
5037
  } catch (e) {
4822
- throw expectedTypeError(field, e, fieldValue);
5038
+ throw new ValidationError({
5039
+ message: "Invalid Array: " + e.message,
5040
+ fields: [field],
5041
+ value: fieldValue
5042
+ });
4823
5043
  }
4824
5044
  }
4825
- if (Array.isArray(value)) {
4826
- for (const [index, item] of value.entries()) {
4827
- try {
4828
- value[index] = convertValueToType(field, item);
4829
- } catch (e) {
4830
- throw expectedTypeError(field, e, item);
5045
+ try {
5046
+ if (Array.isArray(value)) {
5047
+ for (const [index, item] of value.entries()) {
5048
+ if (item !== void 0) {
5049
+ const v = typeof item === "string" ? item.trim() : item;
5050
+ value[index] = convertValueToType(field, v);
5051
+ }
4831
5052
  }
4832
- }
4833
- } else {
4834
- try {
5053
+ } else {
4835
5054
  value = convertValueToType(field, fieldValue);
4836
- } catch (e) {
4837
- throw expectedTypeError(field, e, fieldValue);
4838
5055
  }
5056
+ } catch (e) {
5057
+ throw new ValidationError({
5058
+ message: e.message,
5059
+ fields: [field],
5060
+ value: fieldValue
5061
+ });
5062
+ }
5063
+ if (typeof value === "string" && value === "") {
5064
+ return void 0;
4839
5065
  }
4840
5066
  return value;
4841
5067
  }
@@ -5004,7 +5230,6 @@ function parseFunctionCalls(ai, functionCalls, values, model) {
5004
5230
  }
5005
5231
 
5006
5232
  // dsp/generate.ts
5007
- var colorLog4 = new ColorLog();
5008
5233
  var AxGen = class extends AxProgramWithSignature {
5009
5234
  promptTemplate;
5010
5235
  asserts;
@@ -5069,7 +5294,7 @@ var AxGen = class extends AxProgramWithSignature {
5069
5294
  );
5070
5295
  return res;
5071
5296
  }
5072
- async forwardCore({
5297
+ async *forwardCore({
5073
5298
  ai,
5074
5299
  mem,
5075
5300
  options
@@ -5085,7 +5310,18 @@ var AxGen = class extends AxProgramWithSignature {
5085
5310
  options
5086
5311
  });
5087
5312
  if (res instanceof import_web5.ReadableStream) {
5088
- return await this.processSteamingResponse({
5313
+ yield* this.processStreamingResponse({
5314
+ ai,
5315
+ model,
5316
+ res,
5317
+ usageInfo,
5318
+ mem,
5319
+ traceId,
5320
+ sessionId,
5321
+ functions
5322
+ });
5323
+ } else {
5324
+ yield await this.processResponse({
5089
5325
  ai,
5090
5326
  model,
5091
5327
  res,
@@ -5096,18 +5332,8 @@ var AxGen = class extends AxProgramWithSignature {
5096
5332
  functions
5097
5333
  });
5098
5334
  }
5099
- return await this.processResponse({
5100
- ai,
5101
- model,
5102
- res,
5103
- usageInfo,
5104
- mem,
5105
- traceId,
5106
- sessionId,
5107
- functions
5108
- });
5109
5335
  }
5110
- async processSteamingResponse({
5336
+ async *processStreamingResponse({
5111
5337
  ai,
5112
5338
  model,
5113
5339
  res,
@@ -5119,36 +5345,50 @@ var AxGen = class extends AxProgramWithSignature {
5119
5345
  }) {
5120
5346
  const functionCalls = [];
5121
5347
  const values = {};
5122
- const xstate = { s: -1 };
5348
+ const xstate = {
5349
+ extractedFields: [],
5350
+ s: -1
5351
+ };
5123
5352
  let content = "";
5124
5353
  for await (const v of res) {
5125
- for (const result of v.results ?? []) {
5126
- if (v.modelUsage) {
5127
- this.usage.push({ ...usageInfo, ...v.modelUsage });
5128
- }
5129
- if (result.content) {
5130
- content += result.content;
5131
- mem.updateResult({ name: result.name, content }, sessionId);
5132
- assertStreamingAssertions(
5133
- this.streamingAsserts,
5134
- values,
5135
- xstate,
5136
- content,
5137
- false
5138
- );
5139
- streamingExtractValues(this.signature, values, xstate, content);
5140
- assertAssertions(this.asserts, values);
5141
- }
5142
- if (result.functionCalls) {
5143
- mergeFunctionCalls(functionCalls, result.functionCalls);
5144
- mem.updateResult(
5145
- { name: result.name, content, functionCalls },
5146
- sessionId
5147
- );
5148
- }
5149
- if (result.finishReason === "length") {
5150
- throw new Error("Max tokens reached before completion");
5354
+ const result = v.results[0];
5355
+ if (!result) {
5356
+ continue;
5357
+ }
5358
+ if (v.modelUsage) {
5359
+ this.usage.push({ ...usageInfo, ...v.modelUsage });
5360
+ }
5361
+ if (result.content) {
5362
+ content += result.content;
5363
+ mem.updateResult({ name: result.name, content }, sessionId);
5364
+ const skip = streamingExtractValues(
5365
+ this.signature,
5366
+ values,
5367
+ xstate,
5368
+ content
5369
+ );
5370
+ if (skip) {
5371
+ continue;
5151
5372
  }
5373
+ assertStreamingAssertions(
5374
+ this.streamingAsserts,
5375
+ values,
5376
+ xstate,
5377
+ content,
5378
+ false
5379
+ );
5380
+ assertAssertions(this.asserts, values);
5381
+ yield* streamValues(this.signature, values, xstate, content);
5382
+ }
5383
+ if (result.functionCalls) {
5384
+ mergeFunctionCalls(functionCalls, result.functionCalls);
5385
+ mem.updateResult(
5386
+ { name: result.name, content, functionCalls },
5387
+ sessionId
5388
+ );
5389
+ }
5390
+ if (result.finishReason === "length") {
5391
+ throw new Error("Max tokens reached before completion");
5152
5392
  }
5153
5393
  }
5154
5394
  const funcs = parseFunctionCalls(ai, functionCalls, values, model);
@@ -5166,7 +5406,6 @@ var AxGen = class extends AxProgramWithSignature {
5166
5406
  );
5167
5407
  this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
5168
5408
  }
5169
- streamingExtractFinalValue(values, xstate, content);
5170
5409
  assertStreamingAssertions(
5171
5410
  this.streamingAsserts,
5172
5411
  values,
@@ -5174,8 +5413,9 @@ var AxGen = class extends AxProgramWithSignature {
5174
5413
  content,
5175
5414
  true
5176
5415
  );
5416
+ streamingExtractFinalValue(this.signature, values, xstate, content);
5177
5417
  assertAssertions(this.asserts, values);
5178
- return { ...values };
5418
+ yield* streamValues(this.signature, values, xstate, content);
5179
5419
  }
5180
5420
  async processResponse({
5181
5421
  ai,
@@ -5187,45 +5427,47 @@ var AxGen = class extends AxProgramWithSignature {
5187
5427
  functions
5188
5428
  }) {
5189
5429
  const values = {};
5190
- for (const result of res.results ?? []) {
5191
- if (res.modelUsage) {
5192
- this.usage.push({ ...usageInfo, ...res.modelUsage });
5193
- }
5194
- mem.addResult(result, sessionId);
5195
- if (result.content) {
5196
- extractValues(this.signature, values, result.content);
5197
- assertAssertions(this.asserts, values);
5198
- }
5199
- if (result.functionCalls) {
5200
- const funcs = parseFunctionCalls(ai, result.functionCalls, values);
5201
- if (funcs) {
5202
- if (!functions) {
5203
- throw new Error("Functions are not defined");
5204
- }
5205
- const fx = await processFunctions(
5206
- ai,
5207
- functions,
5208
- funcs,
5209
- mem,
5210
- sessionId,
5211
- traceId
5212
- );
5213
- this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
5430
+ const result = res.results[0];
5431
+ if (!result) {
5432
+ throw new Error("No result found");
5433
+ }
5434
+ if (res.modelUsage) {
5435
+ this.usage.push({ ...usageInfo, ...res.modelUsage });
5436
+ }
5437
+ mem.addResult(result, sessionId);
5438
+ if (result.content) {
5439
+ extractValues(this.signature, values, result.content);
5440
+ assertAssertions(this.asserts, values);
5441
+ }
5442
+ if (result.functionCalls) {
5443
+ const funcs = parseFunctionCalls(ai, result.functionCalls, values);
5444
+ if (funcs) {
5445
+ if (!functions) {
5446
+ throw new Error("Functions are not defined");
5214
5447
  }
5448
+ const fx = await processFunctions(
5449
+ ai,
5450
+ functions,
5451
+ funcs,
5452
+ mem,
5453
+ sessionId,
5454
+ traceId
5455
+ );
5456
+ this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
5215
5457
  }
5216
- if (result.finishReason === "length") {
5217
- throw new Error("Max tokens reached before completion");
5218
- }
5458
+ }
5459
+ if (result.finishReason === "length") {
5460
+ throw new Error("Max tokens reached before completion");
5219
5461
  }
5220
5462
  return { ...values };
5221
5463
  }
5222
- async _forward(ai, values, options, span) {
5464
+ async *_forward2(ai, values, options, span) {
5223
5465
  const stopFunction = (options?.stopFunction ?? this.options?.stopFunction)?.toLowerCase();
5224
- const maxRetries = options?.maxRetries ?? this.options?.maxRetries ?? 3;
5225
- const maxSteps = options?.maxSteps ?? this.options?.maxSteps ?? 10;
5226
- const mem = options?.mem ?? this.options?.mem ?? new AxMemory();
5466
+ const maxRetries = options.maxRetries ?? this.options?.maxRetries ?? 10;
5467
+ const maxSteps = options.maxSteps ?? this.options?.maxSteps ?? 10;
5468
+ const mem = options.mem ?? this.options?.mem ?? new AxMemory();
5227
5469
  let err;
5228
- if (options?.functions && options?.functions.length > 0) {
5470
+ if (options?.functions && options.functions.length > 0) {
5229
5471
  const promptTemplate = this.options?.promptTemplate ?? AxPromptTemplate;
5230
5472
  this.promptTemplate = new promptTemplate(
5231
5473
  this.signature,
@@ -5240,25 +5482,21 @@ var AxGen = class extends AxProgramWithSignature {
5240
5482
  multiStepLoop: for (let n = 0; n < maxSteps; n++) {
5241
5483
  for (let errCount = 0; errCount < maxRetries; errCount++) {
5242
5484
  try {
5243
- const output = await this.forwardCore({
5244
- options,
5245
- ai,
5246
- mem
5247
- });
5248
- const lastMemItem = mem.getLast(options?.sessionId);
5249
- if (lastMemItem) {
5250
- const stopFunctionExecuted = stopFunction && this.functionsExecuted.has(stopFunction);
5251
- if (lastMemItem.role === "function") {
5252
- if (!stopFunction || !stopFunctionExecuted) {
5253
- continue multiStepLoop;
5254
- }
5255
- }
5256
- if (!stopFunctionExecuted) {
5257
- assertRequiredFields(this.signature, output);
5485
+ const generator = this.forwardCore({ options, ai, mem });
5486
+ for await (const delta of generator) {
5487
+ if (delta !== void 0) {
5488
+ yield { version: errCount, delta };
5258
5489
  }
5259
5490
  }
5260
- this.trace = { ...values, ...output };
5261
- return output;
5491
+ const lastMemItem = mem.getLast(options?.sessionId);
5492
+ const shouldContinue = this.shouldContinueSteps(
5493
+ lastMemItem,
5494
+ stopFunction
5495
+ );
5496
+ if (shouldContinue) {
5497
+ continue multiStepLoop;
5498
+ }
5499
+ return;
5262
5500
  } catch (e) {
5263
5501
  let errorFields;
5264
5502
  span?.recordException(e);
@@ -5273,23 +5511,13 @@ var AxGen = class extends AxProgramWithSignature {
5273
5511
  throw e;
5274
5512
  }
5275
5513
  if (errorFields) {
5276
- mem.add(
5277
- {
5278
- role: "user",
5279
- content: this.promptTemplate.renderExtraFields(errorFields)
5280
- },
5281
- options?.sessionId
5514
+ handleValidationError(
5515
+ mem,
5516
+ errorFields,
5517
+ ai,
5518
+ this.promptTemplate,
5519
+ options.sessionId
5282
5520
  );
5283
- mem.addTag("error");
5284
- if (ai.getOptions().debug) {
5285
- process.stdout.write(
5286
- colorLog4.red(
5287
- `Error Correction:
5288
- ${JSON.stringify(errorFields, null, 2)}
5289
- `
5290
- )
5291
- );
5292
- }
5293
5521
  }
5294
5522
  }
5295
5523
  }
@@ -5300,35 +5528,73 @@ ${JSON.stringify(errorFields, null, 2)}
5300
5528
  }
5301
5529
  throw new Error(`Max steps reached: ${maxSteps}`);
5302
5530
  }
5303
- async forward(ai, values, options) {
5531
+ shouldContinueSteps(lastMemItem, stopFunction) {
5532
+ const stopFunctionExecuted = stopFunction && this.functionsExecuted.has(stopFunction);
5533
+ if (lastMemItem?.role === "function" && stopFunction && stopFunctionExecuted) {
5534
+ return false;
5535
+ }
5536
+ if (lastMemItem?.role === "function") {
5537
+ return true;
5538
+ }
5539
+ return false;
5540
+ }
5541
+ async *_forward1(ai, values, options) {
5304
5542
  const tracer = this.options?.tracer ?? options?.tracer;
5305
5543
  let functions = this.functions;
5306
5544
  if (options?.functions) {
5307
5545
  functions = parseFunctions(options.functions, this.functions);
5308
5546
  }
5309
5547
  if (!tracer) {
5310
- return await this._forward(ai, values, {
5548
+ yield* this._forward2(ai, values, {
5311
5549
  ...options,
5312
5550
  functions
5313
5551
  });
5552
+ return;
5314
5553
  }
5315
5554
  const funcNames = functions?.map((f) => f.name).join(",");
5316
5555
  const attributes = {
5317
5556
  ["generate.signature"]: this.signature.toString(),
5318
5557
  ["generate.functions"]: funcNames ?? ""
5319
5558
  };
5320
- return await tracer.startActiveSpan(
5321
- "Generate",
5322
- {
5323
- kind: import_api22.SpanKind.SERVER,
5324
- attributes
5325
- },
5326
- async (span) => {
5327
- const res = this._forward(ai, values, options, span);
5328
- span.end();
5329
- return res;
5559
+ const span = tracer.startSpan("Generate", {
5560
+ kind: import_api22.SpanKind.SERVER,
5561
+ attributes
5562
+ });
5563
+ try {
5564
+ yield* this._forward2(
5565
+ ai,
5566
+ values,
5567
+ {
5568
+ ...options,
5569
+ functions
5570
+ },
5571
+ span
5572
+ );
5573
+ } finally {
5574
+ span.end();
5575
+ }
5576
+ }
5577
+ async forward(ai, values, options) {
5578
+ const generator = this._forward1(ai, values, {
5579
+ ...options
5580
+ });
5581
+ let buffer = {};
5582
+ let currentVersion = 0;
5583
+ for await (const item of generator) {
5584
+ if (item.version !== currentVersion) {
5585
+ buffer = {};
5330
5586
  }
5331
- );
5587
+ currentVersion = item.version;
5588
+ buffer = mergeDeltas(buffer, item.delta);
5589
+ }
5590
+ this.trace = { ...values, ...buffer };
5591
+ return buffer;
5592
+ }
5593
+ async *streamingForward(ai, values, options) {
5594
+ yield* this._forward1(ai, values, {
5595
+ ...options,
5596
+ stream: true
5597
+ });
5332
5598
  }
5333
5599
  };
5334
5600
 
@@ -5418,7 +5684,7 @@ var AxAgent = class {
5418
5684
  func: wrappedFunc
5419
5685
  };
5420
5686
  }
5421
- async forward(ai, values, options) {
5687
+ init(ai, options) {
5422
5688
  const _ai = this.ai ?? ai;
5423
5689
  const funcs = [
5424
5690
  ...options?.functions ?? [],
@@ -5429,26 +5695,15 @@ var AxAgent = class {
5429
5695
  const opt2 = { ...options, functions: funcs };
5430
5696
  this.program = new AxGen(this.signature, opt2);
5431
5697
  }
5432
- if (!options?.tracer) {
5433
- return await this.program.forward(_ai, values, opt);
5434
- }
5435
- const attributes = {
5436
- ["agent.name"]: this.name,
5437
- ["agent.description"]: this.description,
5438
- ["agent.subAgents"]: this.subAgentList ?? "none"
5439
- };
5440
- return await options?.tracer.startActiveSpan(
5441
- "Agent",
5442
- {
5443
- kind: import_api23.SpanKind.SERVER,
5444
- attributes
5445
- },
5446
- async (span) => {
5447
- const res = await this.program.forward(_ai, values, opt);
5448
- span.end();
5449
- return res;
5450
- }
5451
- );
5698
+ return { _ai, opt };
5699
+ }
5700
+ async forward(ai, values, options) {
5701
+ const { _ai, opt } = this.init(ai, options);
5702
+ return await this.program.forward(_ai, values, opt);
5703
+ }
5704
+ async *streamingForward(ai, values, options) {
5705
+ const { _ai, opt } = this.init(ai, options);
5706
+ return yield* this.program.streamingForward(_ai, values, opt);
5452
5707
  }
5453
5708
  };
5454
5709
  function toCamelCase(inputString) {
@@ -5719,7 +5974,7 @@ var randomSample = (array, n) => {
5719
5974
  };
5720
5975
 
5721
5976
  // db/base.ts
5722
- var import_api24 = require("@opentelemetry/api");
5977
+ var import_api23 = require("@opentelemetry/api");
5723
5978
  var AxDBBase = class {
5724
5979
  name;
5725
5980
  fetch;
@@ -5746,7 +6001,7 @@ var AxDBBase = class {
5746
6001
  return await this.tracer?.startActiveSpan(
5747
6002
  "DB Upsert Request",
5748
6003
  {
5749
- kind: import_api24.SpanKind.SERVER,
6004
+ kind: import_api23.SpanKind.SERVER,
5750
6005
  attributes: {
5751
6006
  [axSpanAttributes.DB_SYSTEM]: this.name,
5752
6007
  [axSpanAttributes.DB_OPERATION_NAME]: "upsert",
@@ -5756,9 +6011,11 @@ var AxDBBase = class {
5756
6011
  }
5757
6012
  },
5758
6013
  async (span) => {
5759
- const res = await this._upsert(req, update, { span });
5760
- span.end();
5761
- return res;
6014
+ try {
6015
+ return await this._upsert(req, update, { span });
6016
+ } finally {
6017
+ span.end();
6018
+ }
5762
6019
  }
5763
6020
  );
5764
6021
  }
@@ -5778,7 +6035,7 @@ var AxDBBase = class {
5778
6035
  return await this.tracer?.startActiveSpan(
5779
6036
  "DB Batch Upsert Request",
5780
6037
  {
5781
- kind: import_api24.SpanKind.SERVER,
6038
+ kind: import_api23.SpanKind.SERVER,
5782
6039
  attributes: {
5783
6040
  [axSpanAttributes.DB_SYSTEM]: this.name,
5784
6041
  [axSpanAttributes.DB_OPERATION_NAME]: "upsert",
@@ -5788,9 +6045,11 @@ var AxDBBase = class {
5788
6045
  }
5789
6046
  },
5790
6047
  async (span) => {
5791
- const res = await this._batchUpsert(req, update, { span });
5792
- span.end();
5793
- return res;
6048
+ try {
6049
+ return await this._batchUpsert(req, update, { span });
6050
+ } finally {
6051
+ span.end();
6052
+ }
5794
6053
  }
5795
6054
  );
5796
6055
  }
@@ -5804,7 +6063,7 @@ var AxDBBase = class {
5804
6063
  return await this.tracer?.startActiveSpan(
5805
6064
  "DB Query Request",
5806
6065
  {
5807
- kind: import_api24.SpanKind.SERVER,
6066
+ kind: import_api23.SpanKind.SERVER,
5808
6067
  attributes: {
5809
6068
  [axSpanAttributes.DB_SYSTEM]: this.name,
5810
6069
  [axSpanAttributes.DB_OPERATION_NAME]: "upsert",
@@ -5814,9 +6073,11 @@ var AxDBBase = class {
5814
6073
  }
5815
6074
  },
5816
6075
  async (span) => {
5817
- const res = await this._query(req, { span });
5818
- span.end();
5819
- return res;
6076
+ try {
6077
+ return await this._query(req, { span });
6078
+ } finally {
6079
+ span.end();
6080
+ }
5820
6081
  }
5821
6082
  );
5822
6083
  }
@@ -7083,6 +7344,122 @@ var AxEmbeddingAdapter = class {
7083
7344
  }
7084
7345
  };
7085
7346
 
7347
+ // ai/mock/api.ts
7348
+ var AxMockAIService = class {
7349
+ constructor(config = {}) {
7350
+ this.config = config;
7351
+ }
7352
+ options = {};
7353
+ metrics = {
7354
+ latency: {
7355
+ chat: { mean: 0, p95: 0, p99: 0, samples: [] },
7356
+ embed: { mean: 0, p95: 0, p99: 0, samples: [] }
7357
+ },
7358
+ errors: {
7359
+ chat: { count: 0, rate: 0, total: 0 },
7360
+ embed: { count: 0, rate: 0, total: 0 }
7361
+ }
7362
+ };
7363
+ getName() {
7364
+ return this.config.name ?? "mock-ai-service";
7365
+ }
7366
+ getModelInfo() {
7367
+ return {
7368
+ name: "mock-model",
7369
+ provider: "mock-provider",
7370
+ promptTokenCostPer1M: 100,
7371
+ completionTokenCostPer1M: 100,
7372
+ ...this.config.modelInfo
7373
+ };
7374
+ }
7375
+ getEmbedModelInfo() {
7376
+ return this.config.embedModelInfo;
7377
+ }
7378
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
7379
+ getFeatures(_model) {
7380
+ return {
7381
+ functions: this.config.features?.functions ?? false,
7382
+ streaming: this.config.features?.streaming ?? false
7383
+ };
7384
+ }
7385
+ getModelMap() {
7386
+ return this.config.modelMap;
7387
+ }
7388
+ getMetrics() {
7389
+ return this.metrics;
7390
+ }
7391
+ async chat(req, _options) {
7392
+ if (this.config.latencyMs) {
7393
+ await new Promise((resolve) => setTimeout(resolve, this.config.latencyMs));
7394
+ }
7395
+ if (this.config.shouldError) {
7396
+ throw new Error(this.config.errorMessage ?? "Mock chat error");
7397
+ }
7398
+ this.updateMetrics("chat");
7399
+ if (typeof this.config.chatResponse === "function") {
7400
+ return this.config.chatResponse(req);
7401
+ }
7402
+ return this.config.chatResponse ?? {
7403
+ results: [
7404
+ {
7405
+ content: "Mock response",
7406
+ finishReason: "stop"
7407
+ }
7408
+ ],
7409
+ modelUsage: {
7410
+ promptTokens: 10,
7411
+ completionTokens: 5,
7412
+ totalTokens: 15
7413
+ }
7414
+ };
7415
+ }
7416
+ async embed(req, _options) {
7417
+ if (this.config.latencyMs) {
7418
+ await new Promise((resolve) => setTimeout(resolve, this.config.latencyMs));
7419
+ }
7420
+ if (this.config.shouldError) {
7421
+ throw new Error(this.config.errorMessage ?? "Mock embed error");
7422
+ }
7423
+ this.updateMetrics("embed");
7424
+ if (typeof this.config.embedResponse === "function") {
7425
+ return this.config.embedResponse(req);
7426
+ }
7427
+ return this.config.embedResponse ?? {
7428
+ embeddings: [[0.1, 0.2, 0.3]],
7429
+ modelUsage: {
7430
+ promptTokens: 5,
7431
+ completionTokens: 0,
7432
+ totalTokens: 5
7433
+ }
7434
+ };
7435
+ }
7436
+ setOptions(options) {
7437
+ this.options = options;
7438
+ }
7439
+ getOptions() {
7440
+ return this.options;
7441
+ }
7442
+ updateMetrics(type) {
7443
+ const latency = this.config.latencyMs ?? 0;
7444
+ this.metrics.latency[type].samples.push(latency);
7445
+ const samples = this.metrics.latency[type].samples;
7446
+ this.metrics.latency[type].mean = samples.reduce((a, b) => a + b, 0) / samples.length;
7447
+ if (samples.length > 0) {
7448
+ const sortedSamples = [...samples].sort((a, b) => a - b);
7449
+ const p95Index = Math.max(0, Math.floor(sortedSamples.length * 0.95) - 1);
7450
+ this.metrics.latency[type].p95 = sortedSamples[p95Index] ?? latency;
7451
+ const p99Index = Math.max(0, Math.floor(sortedSamples.length * 0.99) - 1);
7452
+ this.metrics.latency[type].p99 = sortedSamples[p99Index] ?? latency;
7453
+ }
7454
+ if (this.config.shouldError) {
7455
+ this.metrics.errors[type].count++;
7456
+ this.metrics.errors[type].total++;
7457
+ const totalRequests = this.metrics.latency[type].samples.length;
7458
+ this.metrics.errors[type].rate = totalRequests > 0 ? this.metrics.errors[type].count / totalRequests : 0;
7459
+ }
7460
+ }
7461
+ };
7462
+
7086
7463
  // prompts/rag.ts
7087
7464
  var AxRAG = class extends AxChainOfThought {
7088
7465
  genQuery;
@@ -7121,6 +7498,7 @@ var AxRAG = class extends AxChainOfThought {
7121
7498
  AxAI,
7122
7499
  AxAIAnthropic,
7123
7500
  AxAIAnthropicModel,
7501
+ AxAIAnthropicVertexModel,
7124
7502
  AxAIAzureOpenAI,
7125
7503
  AxAICohere,
7126
7504
  AxAICohereEmbedModel,
@@ -7172,6 +7550,7 @@ var AxRAG = class extends AxChainOfThought {
7172
7550
  AxJSInterpreterPermission,
7173
7551
  AxLLMRequestTypeValues,
7174
7552
  AxMemory,
7553
+ AxMockAIService,
7175
7554
  AxProgram,
7176
7555
  AxProgramWithSignature,
7177
7556
  AxPromptTemplate,