@hiper2d/ai-agents 0.5.1 → 0.5.3
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.d.mts +21 -7
- package/dist/index.d.ts +21 -7
- package/dist/index.js +67 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +67 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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];
|
|
@@ -4371,6 +4412,18 @@ ${schemaDescription}`;
|
|
|
4371
4412
|
|
|
4372
4413
|
// src/agents/qwen-agent.ts
|
|
4373
4414
|
import { OpenAI as OpenAI9 } from "openai";
|
|
4415
|
+
function qwenRefusalFrom(model, apiError) {
|
|
4416
|
+
const message = apiError instanceof Error ? apiError.message : String(apiError);
|
|
4417
|
+
if (!/DataInspectionFailed|inappropriate content/i.test(message)) {
|
|
4418
|
+
return void 0;
|
|
4419
|
+
}
|
|
4420
|
+
const detail = message.replace(/^[\s\S]*DataInspectionFailed:\s*/, "").trim();
|
|
4421
|
+
return new ModelRefusalError(
|
|
4422
|
+
model,
|
|
4423
|
+
`${model} refused the prompt (refusalReason: DataInspectionFailed${detail ? `; ${detail}` : ""})`,
|
|
4424
|
+
"DataInspectionFailed"
|
|
4425
|
+
);
|
|
4426
|
+
}
|
|
4374
4427
|
var QwenAgent = class extends AbstractAgent {
|
|
4375
4428
|
client;
|
|
4376
4429
|
// A getter, not a field: `maxOutputTokens` can be raised after construction, and a field
|
|
@@ -4495,7 +4548,7 @@ ${schemaDescription}`;
|
|
|
4495
4548
|
completion = await this.client.chat.completions.create(params);
|
|
4496
4549
|
} catch (apiError) {
|
|
4497
4550
|
this.logger(this.logTemplates.error(this.name, apiError));
|
|
4498
|
-
throw new Error(this.errorMessages.apiError(apiError));
|
|
4551
|
+
throw qwenRefusalFrom(this.model, apiError) ?? new Error(this.errorMessages.apiError(apiError));
|
|
4499
4552
|
}
|
|
4500
4553
|
const rawReply = completion.choices[0]?.message?.content;
|
|
4501
4554
|
if (!rawReply) {
|
|
@@ -4515,6 +4568,9 @@ ${schemaDescription}`;
|
|
|
4515
4568
|
return [validated, thinkingContent, tokenUsage];
|
|
4516
4569
|
} catch (error) {
|
|
4517
4570
|
this.logger(this.logTemplates.error(this.name, error));
|
|
4571
|
+
if (error instanceof ModelError) {
|
|
4572
|
+
throw error;
|
|
4573
|
+
}
|
|
4518
4574
|
throw new Error(this.errorMessages.apiError(error));
|
|
4519
4575
|
}
|
|
4520
4576
|
}
|
|
@@ -4548,7 +4604,7 @@ ${openAIMessages[0].content}`;
|
|
|
4548
4604
|
completion = await this.client.chat.completions.create(params);
|
|
4549
4605
|
} catch (apiError) {
|
|
4550
4606
|
this.logger(this.logTemplates.error(this.name, apiError));
|
|
4551
|
-
throw new Error(this.errorMessages.apiError(apiError));
|
|
4607
|
+
throw qwenRefusalFrom(this.model, apiError) ?? new Error(this.errorMessages.apiError(apiError));
|
|
4552
4608
|
}
|
|
4553
4609
|
const rawReply = completion.choices[0]?.message?.content;
|
|
4554
4610
|
if (!rawReply) {
|
|
@@ -4564,6 +4620,9 @@ ${openAIMessages[0].content}`;
|
|
|
4564
4620
|
return [reply, thinkingContent, tokenUsage];
|
|
4565
4621
|
} catch (error) {
|
|
4566
4622
|
this.logger(this.logTemplates.error(this.name, error));
|
|
4623
|
+
if (error instanceof ModelError) {
|
|
4624
|
+
throw error;
|
|
4625
|
+
}
|
|
4567
4626
|
throw new Error(this.errorMessages.apiError(error));
|
|
4568
4627
|
}
|
|
4569
4628
|
}
|