@hiper2d/ai-agents 0.6.0 → 0.7.0
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 +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +76 -50
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +76 -50
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -370,6 +370,7 @@ declare const LLM_CONSTANTS: {
|
|
|
370
370
|
GLM: string;
|
|
371
371
|
GLM_FLASH: string;
|
|
372
372
|
FUGU_ULTRA: string;
|
|
373
|
+
FUGU_MAX: string;
|
|
373
374
|
QWEN_MAX: string;
|
|
374
375
|
QWEN_FLASH: string;
|
|
375
376
|
MINIMAX: string;
|
|
@@ -527,7 +528,8 @@ declare function getProviderSignatureFields(aiType: string, signature?: string):
|
|
|
527
528
|
* - Gemini 3.x thinkingLevel: minimal|low|medium|high (3.1 Pro and 3.7 Flash reject minimal)
|
|
528
529
|
* - Z.AI GLM-5.3 / 5.3-Flash: low|high|max only
|
|
529
530
|
* - DeepSeek V4: low|high|max (the API itself aliases medium → high)
|
|
530
|
-
* - Sakana Fugu: high|xhigh
|
|
531
|
+
* - Sakana Fugu (verified live 2026-09-20): high|xhigh|max on every model ("low" → 400 naming
|
|
532
|
+
* exactly that enum). The server default is xhigh for fugu-ultra and high for the rest.
|
|
531
533
|
* - Meta Muse Spark (verified 2026-09-12): minimal|low|medium|high|xhigh|max ("none" → 400; max is
|
|
532
534
|
* Standard tier only)
|
|
533
535
|
* - Mistral Small 4 / Medium 3.5 (verified 2026-09-18): the API enum is
|
|
@@ -543,7 +545,7 @@ type AnthropicReasoningEffort = 'low' | 'medium' | 'high' | 'xhigh' | 'max';
|
|
|
543
545
|
type GeminiReasoningEffort = 'minimal' | 'low' | 'medium' | 'high';
|
|
544
546
|
type GlmReasoningEffort = 'low' | 'high' | 'max';
|
|
545
547
|
type DeepSeekReasoningEffort = 'low' | 'high' | 'max';
|
|
546
|
-
type FuguReasoningEffort = 'high' | 'xhigh';
|
|
548
|
+
type FuguReasoningEffort = 'high' | 'xhigh' | 'max';
|
|
547
549
|
type MetaReasoningEffort = 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
|
|
548
550
|
type MistralReasoningEffort = 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';
|
|
549
551
|
/** The shared scale, lowest first. */
|
|
@@ -1651,7 +1653,6 @@ declare class FuguAgent extends AbstractAgent {
|
|
|
1651
1653
|
private readonly errorMessages;
|
|
1652
1654
|
constructor(name: string, instruction: string, model: string, apiKey: string, enableThinking?: boolean, agentLoggingConfig?: AgentLoggingConfig);
|
|
1653
1655
|
private convertToOpenAIMessages;
|
|
1654
|
-
private logRawUsageForCalibration;
|
|
1655
1656
|
private extractThinkingAndUsage;
|
|
1656
1657
|
private prependSystemInstruction;
|
|
1657
1658
|
doAskWithZodSchema<T>(zodSchema: z.ZodSchema<T>, messages: AIMessage[]): Promise<[T, string, TokenUsage$1?, string?]>;
|
package/dist/index.d.ts
CHANGED
|
@@ -370,6 +370,7 @@ declare const LLM_CONSTANTS: {
|
|
|
370
370
|
GLM: string;
|
|
371
371
|
GLM_FLASH: string;
|
|
372
372
|
FUGU_ULTRA: string;
|
|
373
|
+
FUGU_MAX: string;
|
|
373
374
|
QWEN_MAX: string;
|
|
374
375
|
QWEN_FLASH: string;
|
|
375
376
|
MINIMAX: string;
|
|
@@ -527,7 +528,8 @@ declare function getProviderSignatureFields(aiType: string, signature?: string):
|
|
|
527
528
|
* - Gemini 3.x thinkingLevel: minimal|low|medium|high (3.1 Pro and 3.7 Flash reject minimal)
|
|
528
529
|
* - Z.AI GLM-5.3 / 5.3-Flash: low|high|max only
|
|
529
530
|
* - DeepSeek V4: low|high|max (the API itself aliases medium → high)
|
|
530
|
-
* - Sakana Fugu: high|xhigh
|
|
531
|
+
* - Sakana Fugu (verified live 2026-09-20): high|xhigh|max on every model ("low" → 400 naming
|
|
532
|
+
* exactly that enum). The server default is xhigh for fugu-ultra and high for the rest.
|
|
531
533
|
* - Meta Muse Spark (verified 2026-09-12): minimal|low|medium|high|xhigh|max ("none" → 400; max is
|
|
532
534
|
* Standard tier only)
|
|
533
535
|
* - Mistral Small 4 / Medium 3.5 (verified 2026-09-18): the API enum is
|
|
@@ -543,7 +545,7 @@ type AnthropicReasoningEffort = 'low' | 'medium' | 'high' | 'xhigh' | 'max';
|
|
|
543
545
|
type GeminiReasoningEffort = 'minimal' | 'low' | 'medium' | 'high';
|
|
544
546
|
type GlmReasoningEffort = 'low' | 'high' | 'max';
|
|
545
547
|
type DeepSeekReasoningEffort = 'low' | 'high' | 'max';
|
|
546
|
-
type FuguReasoningEffort = 'high' | 'xhigh';
|
|
548
|
+
type FuguReasoningEffort = 'high' | 'xhigh' | 'max';
|
|
547
549
|
type MetaReasoningEffort = 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
|
|
548
550
|
type MistralReasoningEffort = 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';
|
|
549
551
|
/** The shared scale, lowest first. */
|
|
@@ -1651,7 +1653,6 @@ declare class FuguAgent extends AbstractAgent {
|
|
|
1651
1653
|
private readonly errorMessages;
|
|
1652
1654
|
constructor(name: string, instruction: string, model: string, apiKey: string, enableThinking?: boolean, agentLoggingConfig?: AgentLoggingConfig);
|
|
1653
1655
|
private convertToOpenAIMessages;
|
|
1654
|
-
private logRawUsageForCalibration;
|
|
1655
1656
|
private extractThinkingAndUsage;
|
|
1656
1657
|
private prependSystemInstruction;
|
|
1657
1658
|
doAskWithZodSchema<T>(zodSchema: z.ZodSchema<T>, messages: AIMessage[]): Promise<[T, string, TokenUsage$1?, string?]>;
|
package/dist/index.js
CHANGED
|
@@ -976,6 +976,7 @@ var LLM_CONSTANTS = {
|
|
|
976
976
|
GLM: "glm",
|
|
977
977
|
GLM_FLASH: "glm-flash",
|
|
978
978
|
FUGU_ULTRA: "fugu-ultra",
|
|
979
|
+
FUGU_MAX: "fugu-max",
|
|
979
980
|
// Qwen (QwenCloud/DashScope). Stable picker ids without the version, matching the gpt/gemini
|
|
980
981
|
// pattern, so future repoints don't orphan persisted ids.
|
|
981
982
|
QWEN_MAX: "qwen-max",
|
|
@@ -1221,13 +1222,37 @@ var SupportedAiModels = {
|
|
|
1221
1222
|
// so the rate is not even guaranteed stable, and its cache hit rate was 9.3% — effectively
|
|
1222
1223
|
// zero, since every hit came from a duplicate call seconds apart rather than turn-to-turn
|
|
1223
1224
|
// prefix reuse. Ultra costs the same and is predictable.
|
|
1225
|
+
//
|
|
1226
|
+
// reasoningEffort is PINNED on both entries because the server default differs per model:
|
|
1227
|
+
// fugu-ultra defaults to `xhigh` (console.sakana.ai/models), fugu-max to `high`. Until
|
|
1228
|
+
// 2026-09-20 the agent sent no effort at all, so every Ultra turn ran at xhigh. Measured that
|
|
1229
|
+
// day on a 2k-token three-day game prompt (two samples each, chat completions, json mode):
|
|
1230
|
+
// ultra xhigh 148s / 265s $0.34 / $0.50 a turn (orchestration tokens included)
|
|
1231
|
+
// ultra high 65s / 78s $0.16 / $0.17
|
|
1232
|
+
// max high 6s / 10s $0.006 / $0.008
|
|
1233
|
+
// max xhigh 41s / 47s $0.02
|
|
1234
|
+
// `max_tokens` is not a latency lever for Ultra: Sakana applies it to the final response only,
|
|
1235
|
+
// the orchestrator "still uses maximum token limit". Effort is the only knob.
|
|
1224
1236
|
[LLM_CONSTANTS.FUGU_ULTRA]: {
|
|
1225
1237
|
displayName: "Sakana Fugu Ultra",
|
|
1226
1238
|
modelApiName: "fugu-ultra",
|
|
1227
1239
|
apiKeyName: API_KEY_CONSTANTS.FUGU,
|
|
1228
1240
|
hasThinking: false,
|
|
1241
|
+
reasoningEffort: "high",
|
|
1229
1242
|
tags: ["extremely-slow", "expensive"]
|
|
1230
1243
|
},
|
|
1244
|
+
// Fugu Max (2026-09-20, fugu-max → fugu-max-v1.0): Sakana's "largest pool of models on the
|
|
1245
|
+
// cost–performance Pareto frontier" — the everyday Fugu at 5x less than Ultra's output rate
|
|
1246
|
+
// and a fraction of its latency. It reasons (reasoning_tokens 80-500 a turn) but, like
|
|
1247
|
+
// Ultra, never returns reasoning_content, hence hasThinking: false. No orchestration
|
|
1248
|
+
// tokens observed on any call.
|
|
1249
|
+
[LLM_CONSTANTS.FUGU_MAX]: {
|
|
1250
|
+
displayName: "Sakana Fugu Max",
|
|
1251
|
+
modelApiName: "fugu-max",
|
|
1252
|
+
apiKeyName: API_KEY_CONSTANTS.FUGU,
|
|
1253
|
+
hasThinking: false,
|
|
1254
|
+
reasoningEffort: "high"
|
|
1255
|
+
},
|
|
1231
1256
|
// Qwen models (QwenCloud, OpenAI-compatible endpoint). Added 2026-08-05 straight into the
|
|
1232
1257
|
// thinking-only catalog: their API has an `enable_thinking` toggle, we always send true, and
|
|
1233
1258
|
// thinking arrives in `reasoning_content` (verified live against all three, non-streaming).
|
|
@@ -1515,9 +1540,12 @@ var MODEL_PRICING = {
|
|
|
1515
1540
|
extendedContextCacheHitPrice: 1,
|
|
1516
1541
|
extendedContextThresholdTokens: 2e5
|
|
1517
1542
|
},
|
|
1518
|
-
// Sakana Fugu models. Base `fugu` was retired
|
|
1519
|
-
// measured out at these same ultra rates, so it
|
|
1520
|
-
//
|
|
1543
|
+
// Sakana Fugu models (console.sakana.ai/pricing, read 2026-09-20). Base `fugu` was retired
|
|
1544
|
+
// 2026-08-04 — it had no published price and measured out at these same ultra rates, so it
|
|
1545
|
+
// has no pricing entry. fugu-ultra: above 272K context the rates roughly double. Ultra also
|
|
1546
|
+
// reports "orchestration" tokens (its internal expert calls) in prompt_tokens_details /
|
|
1547
|
+
// completion_tokens_details, billed at these same input/output rates — FuguAgent folds them
|
|
1548
|
+
// into the token counts before pricing.
|
|
1521
1549
|
[SupportedAiModels[LLM_CONSTANTS.FUGU_ULTRA].modelApiName]: {
|
|
1522
1550
|
inputPrice: 5,
|
|
1523
1551
|
outputPrice: 30,
|
|
@@ -1527,6 +1555,12 @@ var MODEL_PRICING = {
|
|
|
1527
1555
|
extendedContextCacheHitPrice: 1,
|
|
1528
1556
|
extendedContextThresholdTokens: 272e3
|
|
1529
1557
|
},
|
|
1558
|
+
// fugu-max: flat rates, no context tiers.
|
|
1559
|
+
[SupportedAiModels[LLM_CONSTANTS.FUGU_MAX].modelApiName]: {
|
|
1560
|
+
inputPrice: 2,
|
|
1561
|
+
outputPrice: 6,
|
|
1562
|
+
cacheHitPrice: 0.25
|
|
1563
|
+
},
|
|
1530
1564
|
// Qwen models. Rates from the official pricing page (qwencloud.com/pricing/api, read
|
|
1531
1565
|
// 2026-08-30 — the page is client-rendered, so it was read by eye, not WebFetch):
|
|
1532
1566
|
// qwen3.8-max $2/$6 with implicit-cache hits at $0.25; qwen3.8-flash $0.15/$0.47, hits
|
|
@@ -1643,7 +1677,7 @@ var ANTHROPIC_REASONING_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
|
|
|
1643
1677
|
var GEMINI_REASONING_EFFORTS = ["minimal", "low", "medium", "high"];
|
|
1644
1678
|
var GLM_REASONING_EFFORTS = ["low", "high", "max"];
|
|
1645
1679
|
var DEEPSEEK_REASONING_EFFORTS = ["low", "high", "max"];
|
|
1646
|
-
var FUGU_REASONING_EFFORTS = ["high", "xhigh"];
|
|
1680
|
+
var FUGU_REASONING_EFFORTS = ["high", "xhigh", "max"];
|
|
1647
1681
|
var META_REASONING_EFFORTS = ["minimal", "low", "medium", "high", "xhigh", "max"];
|
|
1648
1682
|
var MISTRAL_REASONING_EFFORTS = ["minimal", "low", "medium", "high", "xhigh"];
|
|
1649
1683
|
function clampReasoningEffort(effort, allowed) {
|
|
@@ -4411,13 +4445,15 @@ var FuguAgent = class extends AbstractAgent {
|
|
|
4411
4445
|
client;
|
|
4412
4446
|
// A getter, not a field: `maxOutputTokens` can be raised after construction, and a field
|
|
4413
4447
|
// initializer would snapshot the default and silently ignore the override.
|
|
4448
|
+
// `reasoning_effort` is re-declared as string: the OpenAI SDK's union lacks Sakana's 'max'.
|
|
4414
4449
|
get defaultParams() {
|
|
4415
4450
|
return {
|
|
4416
4451
|
model: this.model,
|
|
4417
4452
|
stream: false,
|
|
4418
|
-
// Caps
|
|
4419
|
-
//
|
|
4420
|
-
max_tokens: this.maxOutputTokens
|
|
4453
|
+
// Caps the final reply only. Per Sakana's docs the orchestrator "still uses maximum
|
|
4454
|
+
// token limit", so this bounds neither Ultra's latency nor its orchestration spend.
|
|
4455
|
+
max_tokens: this.maxOutputTokens,
|
|
4456
|
+
reasoning_effort: toFuguEffort(this.reasoningEffort ?? "high")
|
|
4421
4457
|
};
|
|
4422
4458
|
}
|
|
4423
4459
|
logTemplates = {
|
|
@@ -4442,33 +4478,6 @@ var FuguAgent = class extends AbstractAgent {
|
|
|
4442
4478
|
content: msg.content
|
|
4443
4479
|
}));
|
|
4444
4480
|
}
|
|
4445
|
-
// ───────────────────────────────────────────────────────────────────────────────────────
|
|
4446
|
-
// TEMPORARY (cost calibration). Base `fugu` is a dynamic router with no published per-token
|
|
4447
|
-
// price and Sakana returns NO cost field in the response — only token counts. Crucially the
|
|
4448
|
-
// response also reports "orchestration tokens" (billed at input/output rates per Sakana's
|
|
4449
|
-
// pricing page) that our standard TokenUsage drops. This logs the full raw breakdown to
|
|
4450
|
-
// BetterStack under a distinctive tag so we can sum real tokens per game and, combined with
|
|
4451
|
-
// the Sakana billing dashboard total, derive the true per-token rate. REMOVE AFTER CALIBRATION.
|
|
4452
|
-
logRawUsageForCalibration(completion) {
|
|
4453
|
-
const usage = completion?.usage;
|
|
4454
|
-
if (!usage) return;
|
|
4455
|
-
logger.info("FUGU_COST_CALIBRATION", {
|
|
4456
|
-
tag: "FUGU_COST_CALIBRATION",
|
|
4457
|
-
model: this.model,
|
|
4458
|
-
agentName: this.name,
|
|
4459
|
-
gameId: this.gameId,
|
|
4460
|
-
userId: this.userId,
|
|
4461
|
-
promptTokens: usage.prompt_tokens ?? 0,
|
|
4462
|
-
completionTokens: usage.completion_tokens ?? 0,
|
|
4463
|
-
totalTokens: usage.total_tokens ?? 0,
|
|
4464
|
-
cachedTokens: usage.prompt_tokens_details?.cached_tokens ?? 0,
|
|
4465
|
-
orchestrationInputTokens: usage.prompt_tokens_details?.orchestration_input_tokens ?? 0,
|
|
4466
|
-
orchestrationInputCachedTokens: usage.prompt_tokens_details?.orchestration_input_cached_tokens ?? 0,
|
|
4467
|
-
reasoningTokens: usage.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
4468
|
-
orchestrationOutputTokens: usage.completion_tokens_details?.orchestration_output_tokens ?? 0,
|
|
4469
|
-
rawUsage: usage
|
|
4470
|
-
});
|
|
4471
|
-
}
|
|
4472
4481
|
extractThinkingAndUsage(completion) {
|
|
4473
4482
|
let thinkingContent = "";
|
|
4474
4483
|
const message = completion.choices[0]?.message;
|
|
@@ -4476,21 +4485,14 @@ var FuguAgent = class extends AbstractAgent {
|
|
|
4476
4485
|
thinkingContent = message.reasoning_content;
|
|
4477
4486
|
this.logger(`Captured reasoning_content (${thinkingContent.length} characters)`);
|
|
4478
4487
|
}
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
totalTokens: usageResult.usage.totalTokens,
|
|
4486
|
-
costUSD: usageResult.cost,
|
|
4487
|
-
...usageResult.usage.cacheHitTokens !== void 0 ? { cachedInputTokens: usageResult.usage.cacheHitTokens } : {}
|
|
4488
|
-
};
|
|
4489
|
-
if (usageResult.usage.reasoningTokens) {
|
|
4490
|
-
const reasoningTokens = usageResult.usage.reasoningTokens;
|
|
4491
|
-
const finalAnswerTokens = Math.max(0, tokenUsage.outputTokens - reasoningTokens);
|
|
4488
|
+
const tokenUsage = extractFuguTokenUsage(this.model, completion);
|
|
4489
|
+
if (tokenUsage) {
|
|
4490
|
+
const details = completion.usage ?? {};
|
|
4491
|
+
const orchestrationIn = details.prompt_tokens_details?.orchestration_input_tokens ?? 0;
|
|
4492
|
+
const orchestrationOut = details.completion_tokens_details?.orchestration_output_tokens ?? 0;
|
|
4493
|
+
if (tokenUsage.reasoningTokens || orchestrationIn || orchestrationOut) {
|
|
4492
4494
|
this.logger(
|
|
4493
|
-
`
|
|
4495
|
+
`Usage breakdown: ${tokenUsage.reasoningTokens ?? 0} reasoning tokens; orchestration ${orchestrationIn} in / ${orchestrationOut} out (billed, folded into the totals)`
|
|
4494
4496
|
);
|
|
4495
4497
|
}
|
|
4496
4498
|
}
|
|
@@ -4532,7 +4534,6 @@ ${schemaDescription}`;
|
|
|
4532
4534
|
this.logger(this.logTemplates.error(this.name, apiError));
|
|
4533
4535
|
throw new Error(this.errorMessages.apiError(apiError));
|
|
4534
4536
|
}
|
|
4535
|
-
this.logRawUsageForCalibration(completion);
|
|
4536
4537
|
const rawReply = completion.choices[0]?.message?.content;
|
|
4537
4538
|
if (!rawReply) {
|
|
4538
4539
|
throw new Error(this.errorMessages.emptyResponse);
|
|
@@ -4576,7 +4577,6 @@ ${schemaDescription}`;
|
|
|
4576
4577
|
this.logger(this.logTemplates.error(this.name, apiError));
|
|
4577
4578
|
throw new Error(this.errorMessages.apiError(apiError));
|
|
4578
4579
|
}
|
|
4579
|
-
this.logRawUsageForCalibration(completion);
|
|
4580
4580
|
const rawReply = completion.choices[0]?.message?.content;
|
|
4581
4581
|
if (!rawReply) {
|
|
4582
4582
|
throw new Error(this.errorMessages.emptyResponse);
|
|
@@ -4595,6 +4595,31 @@ ${schemaDescription}`;
|
|
|
4595
4595
|
}
|
|
4596
4596
|
}
|
|
4597
4597
|
};
|
|
4598
|
+
function extractFuguTokenUsage(modelApiName, completion) {
|
|
4599
|
+
const usage = completion?.usage;
|
|
4600
|
+
if (!usage) {
|
|
4601
|
+
return void 0;
|
|
4602
|
+
}
|
|
4603
|
+
const promptDetails = usage.prompt_tokens_details ?? {};
|
|
4604
|
+
const completionDetails = usage.completion_tokens_details ?? {};
|
|
4605
|
+
const inputTokens = (usage.prompt_tokens ?? 0) + (promptDetails.orchestration_input_tokens ?? 0);
|
|
4606
|
+
const outputTokens = (usage.completion_tokens ?? 0) + (completionDetails.orchestration_output_tokens ?? 0);
|
|
4607
|
+
const cachedInputTokens = (promptDetails.cached_tokens ?? 0) + (promptDetails.orchestration_input_cached_tokens ?? 0);
|
|
4608
|
+
const reasoningTokens = completionDetails.reasoning_tokens ?? 0;
|
|
4609
|
+
return {
|
|
4610
|
+
inputTokens,
|
|
4611
|
+
outputTokens,
|
|
4612
|
+
totalTokens: inputTokens + outputTokens,
|
|
4613
|
+
cachedInputTokens,
|
|
4614
|
+
// Omitted rather than 0: consumers persist the object as-is (see TokenUsage).
|
|
4615
|
+
...reasoningTokens > 0 ? { reasoningTokens } : {},
|
|
4616
|
+
costUSD: calculateModelCost(modelApiName, inputTokens, outputTokens, {
|
|
4617
|
+
cacheHitTokens: cachedInputTokens,
|
|
4618
|
+
// Context-tier selection: the request's own size, not the orchestrator's traffic.
|
|
4619
|
+
contextTokens: usage.total_tokens ?? inputTokens
|
|
4620
|
+
})
|
|
4621
|
+
};
|
|
4622
|
+
}
|
|
4598
4623
|
|
|
4599
4624
|
// src/agents/qwen-agent.ts
|
|
4600
4625
|
var import_openai9 = require("openai");
|
|
@@ -5255,6 +5280,7 @@ var AgentFactory = class {
|
|
|
5255
5280
|
return new GlmAgent(name, instruction, model.modelApiName, key, model.temperature, shouldEnableThinking);
|
|
5256
5281
|
// Sakana Fugu models — always-on reasoning, no temperature (ignored by the model)
|
|
5257
5282
|
case LLM_CONSTANTS.FUGU_ULTRA:
|
|
5283
|
+
case LLM_CONSTANTS.FUGU_MAX:
|
|
5258
5284
|
return new FuguAgent(name, instruction, model.modelApiName, key, shouldEnableThinking);
|
|
5259
5285
|
// Qwen models — thinking-only (enable_thinking always sent)
|
|
5260
5286
|
case LLM_CONSTANTS.QWEN_MAX:
|