@hiper2d/ai-agents 0.5.1 → 0.5.2

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.mjs CHANGED
@@ -714,9 +714,11 @@ var ModelInvalidResponseError = class extends ModelError {
714
714
  }
715
715
  };
716
716
  var ModelRefusalError = class extends ModelError {
717
- constructor(modelType, message = `${modelType} refused to answer (stop_reason: refusal)`) {
717
+ reason;
718
+ constructor(modelType, message = `${modelType} refused to answer (stop_reason: refusal)`, reason) {
718
719
  super(message, modelType);
719
720
  this.name = "ModelRefusalError";
721
+ this.reason = reason;
720
722
  }
721
723
  };
722
724
 
@@ -2654,7 +2656,7 @@ ${schemaDescription}`;
2654
2656
  throw new Error(this.errorMessages.apiError(apiError));
2655
2657
  }
2656
2658
  if (response.stop_reason === "refusal") {
2657
- throw new ModelRefusalError(this.model);
2659
+ throw new ModelRefusalError(this.model, void 0, "refusal");
2658
2660
  }
2659
2661
  if (!("content" in response) || !Array.isArray(response.content) || response.content.length === 0) {
2660
2662
  throw new Error(this.errorMessages.emptyResponse);
@@ -2748,7 +2750,7 @@ ${schemaDescription}`;
2748
2750
  throw new Error(this.errorMessages.apiError(apiError));
2749
2751
  }
2750
2752
  if (response.stop_reason === "refusal") {
2751
- throw new ModelRefusalError(this.model);
2753
+ throw new ModelRefusalError(this.model, void 0, "refusal");
2752
2754
  }
2753
2755
  if (!("content" in response) || !Array.isArray(response.content) || response.content.length === 0) {
2754
2756
  throw new Error(this.errorMessages.emptyResponse);
@@ -2804,6 +2806,45 @@ ${schemaDescription}`;
2804
2806
 
2805
2807
  // src/agents/google-agent.ts
2806
2808
  import { GoogleGenAI as GoogleGenAI3 } from "@google/genai";
2809
+ var GEMINI_REFUSAL_FINISH_REASONS = /* @__PURE__ */ new Set([
2810
+ "SAFETY",
2811
+ "RECITATION",
2812
+ "BLOCKLIST",
2813
+ "PROHIBITED_CONTENT",
2814
+ "SPII",
2815
+ "IMAGE_SAFETY",
2816
+ "IMAGE_PROHIBITED_CONTENT",
2817
+ "IMAGE_RECITATION"
2818
+ ]);
2819
+ function throwForEmptyGeminiResponse(model, response, fallback) {
2820
+ const blockReason = response?.promptFeedback?.blockReason;
2821
+ const candidate = response?.candidates?.[0];
2822
+ const finishReason = candidate?.finishReason;
2823
+ const finishMessage = candidate?.finishMessage;
2824
+ const ratings = (candidate?.safetyRatings ?? response?.promptFeedback?.safetyRatings ?? []).filter((r) => r?.blocked || r?.probability && r.probability !== "NEGLIGIBLE");
2825
+ const ratingText = ratings.length ? `; safetyRatings: ${ratings.map((r) => `${r.category}=${r.probability ?? (r.blocked ? "blocked" : "?")}`).join(", ")}` : "";
2826
+ if (blockReason) {
2827
+ throw new ModelRefusalError(
2828
+ model,
2829
+ `${model} refused the prompt (blockReason: ${blockReason}${finishMessage ? `, ${finishMessage}` : ""}${ratingText})`,
2830
+ blockReason
2831
+ );
2832
+ }
2833
+ if (finishReason && GEMINI_REFUSAL_FINISH_REASONS.has(finishReason)) {
2834
+ throw new ModelRefusalError(
2835
+ model,
2836
+ `${model} refused to answer (finishReason: ${finishReason}${finishMessage ? `, ${finishMessage}` : ""}${ratingText})`,
2837
+ finishReason
2838
+ );
2839
+ }
2840
+ if (finishReason === "MAX_TOKENS") {
2841
+ throw new ModelInvalidResponseError(model, "empty response, finishReason MAX_TOKENS (thinking consumed the whole output budget)", true);
2842
+ }
2843
+ const bits = [`finishReason=${finishReason ?? "none"}`];
2844
+ if (!response?.candidates?.length) bits.push("no candidates");
2845
+ if (finishMessage) bits.push(`finishMessage="${finishMessage}"`);
2846
+ throw new Error(`${fallback} (${bits.join(", ")})`);
2847
+ }
2807
2848
  var GoogleAgent = class extends AbstractAgent {
2808
2849
  client;
2809
2850
  defaultConfig = {
@@ -2815,7 +2856,7 @@ var GoogleAgent = class extends AbstractAgent {
2815
2856
  };
2816
2857
  // Error message templates
2817
2858
  errorMessages = {
2818
- emptyResponse: "Empty response from Google API - check logs for detailed response info",
2859
+ emptyResponse: "Empty response from Google API",
2819
2860
  invalidFormat: "Invalid response format from Google API",
2820
2861
  apiError: (error) => `Failed to get response from Google API: ${error instanceof Error ? error.message : String(error)}`,
2821
2862
  unsupportedRole: (role) => `Unsupported role type: ${role}`
@@ -2987,7 +3028,7 @@ var GoogleAgent = class extends AbstractAgent {
2987
3028
  }
2988
3029
  this.logger(`Zod schema response received - hasText: ${!!response.text}, textLength: ${response.text ? response.text.length : 0}`);
2989
3030
  if (!response.text) {
2990
- throw new Error(this.errorMessages.emptyResponse);
3031
+ throwForEmptyGeminiResponse(this.model, response, this.errorMessages.emptyResponse);
2991
3032
  }
2992
3033
  const parsedData = parseAndValidateLlmJson(response.text, zodSchema, (m) => this.logger(m));
2993
3034
  if (parsedData) {
@@ -3075,7 +3116,7 @@ var GoogleAgent = class extends AbstractAgent {
3075
3116
  }
3076
3117
  this.logger(`Plain text response received - hasText: ${!!response.text}, textLength: ${response.text ? response.text.length : 0}`);
3077
3118
  if (!response.text) {
3078
- throw new Error(this.errorMessages.emptyResponse);
3119
+ throwForEmptyGeminiResponse(this.model, response, this.errorMessages.emptyResponse);
3079
3120
  }
3080
3121
  this.logReply(response.text, thinkingContent || void 0, tokenUsage);
3081
3122
  return [response.text, thinkingContent, tokenUsage, googleThoughtSignature || void 0];