@agentforge/tools 0.18.5 → 0.18.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -977,47 +977,33 @@ var webSearch = core.toolBuilder().name("web-search").description(
977
977
  };
978
978
  }
979
979
  }).build();
980
- function createGetConfiguredSlackClient(token, botName = "AgentForge Bot", botIcon = ":robot_face:") {
981
- let configuredClient = null;
982
- return function getConfiguredSlackClient() {
983
- if (!configuredClient) {
984
- const slackToken = token || process.env.SLACK_USER_TOKEN || process.env.SLACK_BOT_TOKEN;
985
- if (!slackToken) {
986
- throw new Error(
987
- "Slack token not configured. Please provide a token in config or set SLACK_USER_TOKEN or SLACK_BOT_TOKEN environment variable."
988
- );
980
+ function createLazySlackClient(resolveToken, config, missingTokenError) {
981
+ let client = null;
982
+ return () => {
983
+ const token = resolveToken();
984
+ if (!client) {
985
+ if (!token) {
986
+ throw new Error(missingTokenError);
989
987
  }
990
- configuredClient = new webApi.WebClient(slackToken);
988
+ client = new webApi.WebClient(token);
991
989
  }
992
- return {
993
- client: configuredClient,
994
- config: {
995
- token: token || process.env.SLACK_USER_TOKEN || process.env.SLACK_BOT_TOKEN || "",
996
- botName,
997
- botIcon
998
- }
999
- };
990
+ return { client, config: { token: token || "", ...config } };
1000
991
  };
1001
992
  }
1002
- var defaultSlackClient = null;
993
+ function createGetConfiguredSlackClient(token, botName = "AgentForge Bot", botIcon = ":robot_face:") {
994
+ return createLazySlackClient(
995
+ () => token || process.env.SLACK_USER_TOKEN || process.env.SLACK_BOT_TOKEN,
996
+ { botName, botIcon },
997
+ "Slack token not configured. Please provide a token in config or set SLACK_USER_TOKEN or SLACK_BOT_TOKEN environment variable."
998
+ );
999
+ }
1000
+ var getLazyDefaultSlackClient = createLazySlackClient(
1001
+ () => process.env.SLACK_USER_TOKEN || process.env.SLACK_BOT_TOKEN,
1002
+ { botName: "AgentForge Bot", botIcon: ":robot_face:" },
1003
+ "Slack token not configured. Please set SLACK_USER_TOKEN or SLACK_BOT_TOKEN environment variable."
1004
+ );
1003
1005
  function getDefaultSlackClient() {
1004
- if (!defaultSlackClient) {
1005
- const token = process.env.SLACK_USER_TOKEN || process.env.SLACK_BOT_TOKEN;
1006
- if (!token) {
1007
- throw new Error(
1008
- "Slack token not configured. Please set SLACK_USER_TOKEN or SLACK_BOT_TOKEN environment variable."
1009
- );
1010
- }
1011
- defaultSlackClient = new webApi.WebClient(token);
1012
- }
1013
- return {
1014
- client: defaultSlackClient,
1015
- config: {
1016
- token: process.env.SLACK_USER_TOKEN || process.env.SLACK_BOT_TOKEN || "",
1017
- botName: "AgentForge Bot",
1018
- botIcon: ":robot_face:"
1019
- }
1020
- };
1006
+ return getLazyDefaultSlackClient();
1021
1007
  }
1022
1008
  function createSendSlackMessageTool(getSlackClient, logger20) {
1023
1009
  return core.toolBuilder().name("send-slack-message").description("Send a message to a Slack channel for team communication and notifications").category(core.ToolCategory.WEB).tags(["slack", "messaging", "communication"]).usageNotes(
@@ -2904,6 +2890,61 @@ var OpenAIEmbeddingProvider = class {
2904
2890
  });
2905
2891
  }
2906
2892
  };
2893
+ async function generateHostedEmbedding(text, model, generateBatch) {
2894
+ const result = await generateBatch([text], model);
2895
+ return {
2896
+ embedding: result.embeddings[0],
2897
+ model: result.model,
2898
+ dimensions: result.dimensions,
2899
+ usage: result.usage
2900
+ };
2901
+ }
2902
+ function generateHostedBatchEmbeddings({
2903
+ texts,
2904
+ model,
2905
+ request: request2,
2906
+ formatError
2907
+ }) {
2908
+ return retryWithBackoff2(async () => {
2909
+ try {
2910
+ const { embeddings, usage } = await request2(texts, model);
2911
+ return {
2912
+ embeddings,
2913
+ model,
2914
+ dimensions: embeddings[0]?.length || 0,
2915
+ usage
2916
+ };
2917
+ } catch (error) {
2918
+ if (!axios5__default.default.isAxiosError(error)) throw error;
2919
+ const status = error.response?.status;
2920
+ const providerMessage = error.response?.data?.message || error.message;
2921
+ throw withProviderErrorMetadata(
2922
+ error,
2923
+ formatError({
2924
+ kind: classifyHttpError(status),
2925
+ status,
2926
+ providerMessage
2927
+ })
2928
+ );
2929
+ }
2930
+ });
2931
+ }
2932
+ function classifyHttpError(status) {
2933
+ if (status === 401) return "authentication";
2934
+ if (status === 429) return "rate-limit";
2935
+ if (status === 400) return "invalid-request";
2936
+ return "other";
2937
+ }
2938
+
2939
+ // src/data/neo4j/embeddings/providers/cohere.ts
2940
+ function formatCohereError({ kind, status, providerMessage }) {
2941
+ if (kind === "authentication") {
2942
+ return `Cohere API authentication failed. Please check your COHERE_API_KEY. ${providerMessage}`;
2943
+ }
2944
+ if (kind === "rate-limit") return `Cohere API rate limit exceeded. ${providerMessage}`;
2945
+ if (kind === "invalid-request") return `Cohere API request invalid: ${providerMessage}`;
2946
+ return `Cohere API error (${status}): ${providerMessage}`;
2947
+ }
2907
2948
  var CohereEmbeddingProvider = class {
2908
2949
  name = "cohere";
2909
2950
  defaultModel = "embed-english-v3.0";
@@ -2919,62 +2960,43 @@ var CohereEmbeddingProvider = class {
2919
2960
  return !!this.apiKey;
2920
2961
  }
2921
2962
  async generateEmbedding(text, model) {
2922
- const result = await this.generateBatchEmbeddings([text], model);
2923
- return {
2924
- embedding: result.embeddings[0],
2925
- model: result.model,
2926
- dimensions: result.dimensions,
2927
- usage: result.usage
2928
- };
2963
+ return generateHostedEmbedding(
2964
+ text,
2965
+ model,
2966
+ (texts, batchModel) => this.generateBatchEmbeddings(texts, batchModel)
2967
+ );
2929
2968
  }
2930
2969
  async generateBatchEmbeddings(texts, model) {
2931
2970
  const modelToUse = model || this.defaultModel;
2932
- return retryWithBackoff2(async () => {
2933
- try {
2971
+ return generateHostedBatchEmbeddings({
2972
+ texts,
2973
+ model: modelToUse,
2974
+ formatError: formatCohereError,
2975
+ request: async (requestTexts, requestModel) => {
2934
2976
  const response = await axios5__default.default.post(
2935
2977
  `${this.baseUrl}/embed`,
2936
2978
  {
2937
- texts,
2938
- model: modelToUse,
2979
+ texts: requestTexts,
2980
+ model: requestModel,
2939
2981
  input_type: "search_document",
2940
2982
  // For storing in vector DB
2941
2983
  embedding_types: ["float"]
2942
2984
  },
2943
2985
  {
2944
2986
  headers: {
2945
- "Authorization": `Bearer ${this.apiKey}`,
2987
+ Authorization: `Bearer ${this.apiKey}`,
2946
2988
  "Content-Type": "application/json"
2947
2989
  }
2948
2990
  }
2949
2991
  );
2950
2992
  const embeddings = response.data.embeddings.float;
2951
- const dimensions = embeddings[0]?.length || 0;
2952
2993
  return {
2953
2994
  embeddings,
2954
- model: modelToUse,
2955
- dimensions,
2956
2995
  usage: response.data.meta?.billed_units ? {
2957
2996
  promptTokens: response.data.meta.billed_units.input_tokens || 0,
2958
2997
  totalTokens: response.data.meta.billed_units.input_tokens || 0
2959
2998
  } : void 0
2960
2999
  };
2961
- } catch (error) {
2962
- if (axios5__default.default.isAxiosError(error)) {
2963
- const status = error.response?.status;
2964
- const providerMessage = error.response?.data?.message || error.message;
2965
- let message;
2966
- if (status === 401) {
2967
- message = `Cohere API authentication failed. Please check your COHERE_API_KEY. ${providerMessage}`;
2968
- } else if (status === 429) {
2969
- message = `Cohere API rate limit exceeded. ${providerMessage}`;
2970
- } else if (status === 400) {
2971
- message = `Cohere API request invalid: ${providerMessage}`;
2972
- } else {
2973
- message = `Cohere API error (${status}): ${providerMessage}`;
2974
- }
2975
- throw withProviderErrorMetadata(error, message);
2976
- }
2977
- throw error;
2978
3000
  }
2979
3001
  });
2980
3002
  }
@@ -2994,77 +3016,51 @@ var HuggingFaceEmbeddingProvider = class {
2994
3016
  return !!this.apiKey;
2995
3017
  }
2996
3018
  async generateEmbedding(text, model) {
2997
- const modelToUse = model || this.defaultModel;
2998
- return retryWithBackoff2(async () => {
2999
- try {
3000
- const response = await axios5__default.default.post(
3001
- `${this.baseUrl}/${modelToUse}`,
3002
- {
3003
- inputs: text,
3004
- options: {
3005
- wait_for_model: true
3006
- }
3007
- },
3008
- {
3009
- headers: {
3010
- "Authorization": `Bearer ${this.apiKey}`,
3011
- "Content-Type": "application/json"
3012
- }
3013
- }
3014
- );
3015
- const embedding = Array.isArray(response.data) ? response.data : response.data[0];
3016
- return {
3017
- embedding,
3018
- model: modelToUse,
3019
- dimensions: embedding.length
3020
- };
3021
- } catch (error) {
3022
- if (axios5__default.default.isAxiosError(error)) {
3023
- const status = error.response?.status;
3024
- const message = error.response?.data?.error || error.message;
3025
- let messageText;
3026
- if (status === 401) {
3027
- messageText = `HuggingFace API authentication failed. Please check your HUGGINGFACE_API_KEY. ${message}`;
3028
- } else if (status === 429) {
3029
- messageText = `HuggingFace API rate limit exceeded. ${message}`;
3030
- } else if (status === 400) {
3031
- messageText = `HuggingFace API request invalid: ${message}`;
3032
- } else if (status === 503) {
3033
- messageText = `HuggingFace model is loading. Please retry in a moment. ${message}`;
3034
- } else {
3035
- messageText = `HuggingFace API error (${status}): ${message}`;
3036
- }
3037
- throw withProviderErrorMetadata(error, messageText);
3038
- }
3039
- throw error;
3040
- }
3041
- });
3019
+ const { data, model: modelToUse } = await this.requestEmbeddings(
3020
+ text,
3021
+ model
3022
+ );
3023
+ const embedding = Array.isArray(data) ? data : data[0];
3024
+ return {
3025
+ embedding,
3026
+ model: modelToUse,
3027
+ dimensions: embedding.length
3028
+ };
3042
3029
  }
3043
3030
  async generateBatchEmbeddings(texts, model) {
3031
+ const { data: embeddings, model: modelToUse } = await this.requestEmbeddings(
3032
+ texts,
3033
+ model
3034
+ );
3035
+ const dimensions = embeddings[0]?.length || 0;
3036
+ return {
3037
+ embeddings,
3038
+ model: modelToUse,
3039
+ dimensions
3040
+ };
3041
+ }
3042
+ async requestEmbeddings(inputs, model) {
3044
3043
  const modelToUse = model || this.defaultModel;
3045
3044
  return retryWithBackoff2(async () => {
3046
3045
  try {
3047
3046
  const response = await axios5__default.default.post(
3048
3047
  `${this.baseUrl}/${modelToUse}`,
3049
3048
  {
3050
- inputs: texts,
3049
+ inputs,
3051
3050
  options: {
3052
3051
  wait_for_model: true
3053
3052
  }
3054
3053
  },
3055
3054
  {
3056
3055
  headers: {
3057
- "Authorization": `Bearer ${this.apiKey}`,
3056
+ Authorization: `Bearer ${this.apiKey}`,
3058
3057
  "Content-Type": "application/json"
3059
3058
  }
3060
3059
  }
3061
3060
  );
3062
- const embeddings = response.data;
3063
- const dimensions = embeddings[0]?.length || 0;
3064
3061
  return {
3065
- embeddings,
3066
- model: modelToUse,
3067
- dimensions
3062
+ data: response.data,
3063
+ model: modelToUse
3068
3064
  };
3069
3065
  } catch (error) {
3070
3066
  if (axios5__default.default.isAxiosError(error)) {
@@ -3089,6 +3085,14 @@ var HuggingFaceEmbeddingProvider = class {
3089
3085
  });
3090
3086
  }
3091
3087
  };
3088
+ function formatVoyageError({ kind, status, providerMessage }) {
3089
+ if (kind === "authentication") {
3090
+ return `Voyage AI API authentication failed. Please check your VOYAGE_API_KEY. ${providerMessage}`;
3091
+ }
3092
+ if (kind === "rate-limit") return `Voyage AI API rate limit exceeded. ${providerMessage}`;
3093
+ if (kind === "invalid-request") return `Voyage AI API request invalid: ${providerMessage}`;
3094
+ return `Voyage AI API error (${status}): ${providerMessage}`;
3095
+ }
3092
3096
  var VoyageEmbeddingProvider = class {
3093
3097
  name = "voyage";
3094
3098
  defaultModel = "voyage-2";
@@ -3104,61 +3108,44 @@ var VoyageEmbeddingProvider = class {
3104
3108
  return !!this.apiKey;
3105
3109
  }
3106
3110
  async generateEmbedding(text, model) {
3107
- const result = await this.generateBatchEmbeddings([text], model);
3108
- return {
3109
- embedding: result.embeddings[0],
3110
- model: result.model,
3111
- dimensions: result.dimensions,
3112
- usage: result.usage
3113
- };
3111
+ return generateHostedEmbedding(
3112
+ text,
3113
+ model,
3114
+ (texts, batchModel) => this.generateBatchEmbeddings(texts, batchModel)
3115
+ );
3114
3116
  }
3115
3117
  async generateBatchEmbeddings(texts, model) {
3116
3118
  const modelToUse = model || this.defaultModel;
3117
- return retryWithBackoff2(async () => {
3118
- try {
3119
+ return generateHostedBatchEmbeddings({
3120
+ texts,
3121
+ model: modelToUse,
3122
+ formatError: formatVoyageError,
3123
+ request: async (requestTexts, requestModel) => {
3119
3124
  const response = await axios5__default.default.post(
3120
3125
  `${this.baseUrl}/embeddings`,
3121
3126
  {
3122
- input: texts,
3123
- model: modelToUse,
3127
+ input: requestTexts,
3128
+ model: requestModel,
3124
3129
  input_type: "document"
3125
3130
  // For storing in vector DB
3126
3131
  },
3127
3132
  {
3128
3133
  headers: {
3129
- "Authorization": `Bearer ${this.apiKey}`,
3134
+ Authorization: `Bearer ${this.apiKey}`,
3130
3135
  "Content-Type": "application/json"
3131
3136
  }
3132
3137
  }
3133
3138
  );
3134
- const embeddings = response.data.data.map((item) => item.embedding);
3135
- const dimensions = embeddings[0]?.length || 0;
3139
+ const embeddings = response.data.data.map(
3140
+ (item) => item.embedding
3141
+ );
3136
3142
  return {
3137
3143
  embeddings,
3138
- model: modelToUse,
3139
- dimensions,
3140
3144
  usage: response.data.usage ? {
3141
3145
  promptTokens: response.data.usage.total_tokens || 0,
3142
3146
  totalTokens: response.data.usage.total_tokens || 0
3143
3147
  } : void 0
3144
3148
  };
3145
- } catch (error) {
3146
- if (axios5__default.default.isAxiosError(error)) {
3147
- const status = error.response?.status;
3148
- const message = error.response?.data?.message || error.message;
3149
- let messageText;
3150
- if (status === 401) {
3151
- messageText = `Voyage AI API authentication failed. Please check your VOYAGE_API_KEY. ${message}`;
3152
- } else if (status === 429) {
3153
- messageText = `Voyage AI API rate limit exceeded. ${message}`;
3154
- } else if (status === 400) {
3155
- messageText = `Voyage AI API request invalid: ${message}`;
3156
- } else {
3157
- messageText = `Voyage AI API error (${status}): ${message}`;
3158
- }
3159
- throw withProviderErrorMetadata(error, messageText);
3160
- }
3161
- throw error;
3162
3149
  }
3163
3150
  });
3164
3151
  }
@@ -7201,15 +7188,6 @@ function formatTableName(table) {
7201
7188
  return table.schema ? `${table.schema}.${table.name}` : table.name;
7202
7189
  }
7203
7190
 
7204
- // src/data/relational/schema/type-mapper-normalization.ts
7205
- function normaliseDbType(raw) {
7206
- let type = raw.toLowerCase().trim();
7207
- type = type.replace(/\[\]$/, "");
7208
- type = type.replace(/\([\d,\s]+\)/, "");
7209
- type = type.replace(/\s+unsigned$/, "");
7210
- return type.trim();
7211
- }
7212
-
7213
7191
  // src/data/relational/schema/type-mapper-vendor-maps.ts
7214
7192
  var POSTGRES_TYPE_MAP = {
7215
7193
  smallint: "number",
@@ -7385,6 +7363,13 @@ function getVendorTypeMap(vendor) {
7385
7363
  function usesStringPrecisionFallback(vendor, normalised) {
7386
7364
  return (normalised === "bigint" || normalised === "int8" || normalised === "bigserial") && (vendor === "postgresql" || vendor === "mysql");
7387
7365
  }
7366
+ function normaliseDbType(raw) {
7367
+ let type = raw.toLowerCase().trim();
7368
+ type = type.replace(/\[\]$/, "");
7369
+ type = type.replace(/\([\d,\s]+\)/, "");
7370
+ type = type.replace(/\s+unsigned$/, "");
7371
+ return type.trim();
7372
+ }
7388
7373
  var logger14 = core.createLogger("agentforge:tools:data:relational:schema-diff");
7389
7374
  function diffSchemas(before, after) {
7390
7375
  const tableDiffs = [];