@code-yeongyu/senpi-ai 2026.11.5-1 → 2026.11.6-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.
@@ -23,6 +23,15 @@ export type PromptCacheLifetime = {
23
23
  readonly kind: "none";
24
24
  };
25
25
  export declare function isAnthropicApiBaseUrl(baseUrl: string): boolean;
26
+ export declare function allowsAnthropicLongCacheRetention(model: Model<"anthropic-messages">): boolean;
27
+ /**
28
+ * Whether this Anthropic-messages host applies `cache_control` at all, and therefore whether warming its
29
+ * prompt cache can achieve anything. The native host always does. A proxy does only when its model entry
30
+ * asserts cache support with `compat.supportsLongCacheRetention: true` — the documented assertion for a
31
+ * gateway that honours `cache_control` — because an unset or `false` flag cannot tell a host that caches
32
+ * for five minutes without the one-hour option apart from one that ignores `cache_control`.
33
+ */
34
+ export declare function supportsAnthropicCacheWarming(model: Model<"anthropic-messages">): boolean;
26
35
  export declare function getAnthropicCompat(model: Model<"anthropic-messages">): Required<Omit<AnthropicMessagesCompat, "forceAdaptiveThinking" | "supportsMidConvoEffort" | "sessionAffinityFormat">> & Pick<AnthropicMessagesCompat, "sessionAffinityFormat">;
27
36
  export type ResolvedOpenAICompletionsCompat = Omit<Required<OpenAICompletionsCompat>, "vllmPriority" | "cacheControlFormat" | "toolCallFormat" | "deferredToolsMode" | "toolSchemaFlavor" | "supportsPromptCacheKey" | "chatTemplateArgs" | "supportsThinkingTokenBudget" | "thinkingTokenBudgetField" | "veniceParameters" | "supportsForcedToolChoice" | "supportsWebSearch" | "mixedStrictTools"> & {
28
37
  mixedStrictTools?: OpenAICompletionsCompat["mixedStrictTools"];
@@ -50,6 +50,20 @@ function defaultSupportsToolReferences(model) {
50
50
  const minor = version[2] && version[2].length < 8 ? Number(version[2]) : 0;
51
51
  return major > 4 || (major === 4 && minor >= 5);
52
52
  }
53
+ export function allowsAnthropicLongCacheRetention(model) {
54
+ return (model.compat?.supportsLongCacheRetention ??
55
+ (isAnthropicApiBaseUrl(model.baseUrl) && getAnthropicCompat(model).supportsLongCacheRetention));
56
+ }
57
+ /**
58
+ * Whether this Anthropic-messages host applies `cache_control` at all, and therefore whether warming its
59
+ * prompt cache can achieve anything. The native host always does. A proxy does only when its model entry
60
+ * asserts cache support with `compat.supportsLongCacheRetention: true` — the documented assertion for a
61
+ * gateway that honours `cache_control` — because an unset or `false` flag cannot tell a host that caches
62
+ * for five minutes without the one-hour option apart from one that ignores `cache_control`.
63
+ */
64
+ export function supportsAnthropicCacheWarming(model) {
65
+ return isAnthropicApiBaseUrl(model.baseUrl) || model.compat?.supportsLongCacheRetention === true;
66
+ }
53
67
  export function getAnthropicCompat(model) {
54
68
  // Auto-detect session affinity and cache control support from provider
55
69
  const isFireworks = model.provider === "fireworks";
@@ -381,9 +395,7 @@ export function resolvePromptCacheLifetime(model, env) {
381
395
  const retention = resolveAnthropicCacheRetention(anthropicModel.cacheRetention, env, "short");
382
396
  if (retention === "none")
383
397
  return NO_PROMPT_CACHE;
384
- return retention === "long" &&
385
- isAnthropicApiBaseUrl(anthropicModel.baseUrl) &&
386
- getAnthropicCompat(anthropicModel).supportsLongCacheRetention
398
+ return retention === "long" && allowsAnthropicLongCacheRetention(anthropicModel)
387
399
  ? ttl(PROMPT_CACHE_TTL_LONG_SECONDS)
388
400
  : ttl(PROMPT_CACHE_TTL_SHORT_SECONDS);
389
401
  }
@@ -2,9 +2,10 @@ import { redactCredentialShapes, redactSecrets } from "./secret-redaction.js";
2
2
  export { redactCredentialShapes, redactSecrets };
3
3
  // A route that does not serve a configured model id: the OpenAI-compatible `model_not_found` code and OpenAI's
4
4
  // "The model `<id>` does not exist" prose, a gateway's "unknown provider for model", Anthropic's not_found_error whose
5
- // message names the model ("model: <id>"; any other not_found_error is not one), and Google's "models/<id> is not found".
5
+ // message names the model ("model: <id>"; any other not_found_error is not one), Google's "models/<id> is not found",
6
+ // and an OpenAI-compatible gateway's image allowlist reply "Model <id> is not supported on /v1/images/generations".
6
7
  // Every quantifier is bounded, so a long run never makes a match attempt expensive.
7
- const MODEL_CONFIG_ERROR = /\bmodel_not_found\b|\bunknown provider for model\b|\bthe model\s{1,8}[`'"]?[\w.:/-]{1,256}[`'"]?\s{1,8}does not exist\b|\bnot_found_error\b[^}]{0,120}?\bmodel:\s{0,8}[\w.:/-]|\bmodels\/[\w.:-]{1,256} is not found\b/i;
8
+ const MODEL_CONFIG_ERROR = /\bmodel_not_found\b|\bunknown provider for model\b|\bmodel\s{1,8}[\w.:/-]{1,256}\s{1,8}is not supported on \/v1\/images\b|\bthe model\s{1,8}[`'"]?[\w.:/-]{1,256}[`'"]?\s{1,8}does not exist\b|\bnot_found_error\b[^}]{0,120}?\bmodel:\s{0,8}[\w.:/-]|\bmodels\/[\w.:-]{1,256} is not found\b/i;
8
9
  /** True when provider text says the route does not serve the configured model id (senpi#4282). */
9
10
  export function isModelConfigError(errorMessage) {
10
11
  return errorMessage !== undefined && MODEL_CONFIG_ERROR.test(errorMessage);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi-ai",
3
- "version": "2026.11.5-1",
3
+ "version": "2026.11.6-2",
4
4
  "description": "Unified LLM API with automatic model discovery and provider configuration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -88,7 +88,7 @@
88
88
  "dependencies": {
89
89
  "@anthropic-ai/sdk": "0.127.0",
90
90
  "@aws-sdk/client-bedrock-runtime": "3.1136.0",
91
- "@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.11.5-1",
91
+ "@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.11.6-2",
92
92
  "@google/genai": "2.23.0",
93
93
  "@smithy/node-http-handler": "4.12.1",
94
94
  "google-auth-library": "10.6.2",