@code-yeongyu/senpi-ai 2026.9.30 → 2026.10.1

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.
Files changed (274) hide show
  1. package/README.md +189 -19
  2. package/dist/api/anthropic-messages.js +168 -32
  3. package/dist/api/azure-openai-responses.js +23 -10
  4. package/dist/api/bedrock-converse-stream.js +12 -4
  5. package/dist/api/cloudflare-workers-ai-system-one.d.ts +4 -0
  6. package/dist/api/cloudflare-workers-ai-system-one.js +43 -0
  7. package/dist/api/cloudflare-workers-ai-system-one.lazy.d.ts +3 -0
  8. package/dist/api/cloudflare-workers-ai-system-one.lazy.js +4 -0
  9. package/dist/api/cloudflare.d.ts +2 -0
  10. package/dist/api/cloudflare.js +2 -0
  11. package/dist/api/context-room.d.ts +2 -2
  12. package/dist/api/cursor-agent.js +19 -10
  13. package/dist/api/devin-agent/request.d.ts +9 -9
  14. package/dist/api/devin-agent/request.js +14 -10
  15. package/dist/api/google-generative-ai.js +20 -80
  16. package/dist/api/google-shared.d.ts +13 -4
  17. package/dist/api/google-shared.js +54 -4
  18. package/dist/api/google-vertex.js +19 -62
  19. package/dist/api/llama-cpp-classify.d.ts +33 -0
  20. package/dist/api/llama-cpp-classify.js +365 -0
  21. package/dist/api/llama-cpp-classify.lazy.d.ts +3 -0
  22. package/dist/api/llama-cpp-classify.lazy.js +4 -0
  23. package/dist/api/mistral-conversations.d.ts +1 -1
  24. package/dist/api/mistral-conversations.js +36 -29
  25. package/dist/api/openai-codex-responses.d.ts +1 -1
  26. package/dist/api/openai-codex-responses.js +72 -37
  27. package/dist/api/openai-completions.d.ts +3 -2
  28. package/dist/api/openai-completions.js +76 -50
  29. package/dist/api/openai-images-params.d.ts +2 -2
  30. package/dist/api/openai-images.d.ts +1 -1
  31. package/dist/api/openai-responses-shared.d.ts +31 -8
  32. package/dist/api/openai-responses-shared.js +115 -27
  33. package/dist/api/openai-responses.d.ts +1 -1
  34. package/dist/api/openai-responses.js +38 -33
  35. package/dist/api/openrouter-images.d.ts +2 -1
  36. package/dist/api/openrouter-images.js +1 -0
  37. package/dist/api/pi-messages.d.ts +3 -3
  38. package/dist/api/pi-messages.js +3 -2
  39. package/dist/api/simple-options.d.ts +2 -2
  40. package/dist/api/simple-options.js +1 -0
  41. package/dist/api/system-one-shared.d.ts +23 -0
  42. package/dist/api/system-one-shared.js +183 -0
  43. package/dist/api/transform-messages.js +5 -2
  44. package/dist/api/typesafe-system-one.d.ts +4 -0
  45. package/dist/api/typesafe-system-one.js +19 -0
  46. package/dist/api/typesafe-system-one.lazy.d.ts +3 -0
  47. package/dist/api/typesafe-system-one.lazy.js +4 -0
  48. package/dist/api-registry.d.ts +3 -3
  49. package/dist/auth/helpers.js +1 -1
  50. package/dist/auth/oauth/anthropic-callback-listener.js +1 -1
  51. package/dist/auth/oauth/callback-server.d.ts +55 -0
  52. package/dist/auth/oauth/callback-server.js +146 -0
  53. package/dist/auth/oauth/chatgpt-subscription.d.ts +1 -1
  54. package/dist/auth/oauth/chatgpt-subscription.js +20 -124
  55. package/dist/auth/oauth/devin-callback.js +1 -1
  56. package/dist/auth/oauth/load.d.ts +4 -0
  57. package/dist/auth/oauth/load.js +10 -0
  58. package/dist/auth/oauth/meta.d.ts +17 -0
  59. package/dist/auth/oauth/meta.js +190 -0
  60. package/dist/auth/oauth/openai-chatgpt.d.ts +9 -0
  61. package/dist/auth/oauth/openai-chatgpt.js +266 -0
  62. package/dist/auth/oauth/openrouter.d.ts +1 -1
  63. package/dist/auth/oauth/openrouter.js +19 -138
  64. package/dist/auth/oauth/radius.d.ts +1 -1
  65. package/dist/auth/oauth/radius.js +21 -89
  66. package/dist/auth/resolve.d.ts +3 -8
  67. package/dist/auth/resolve.js +3 -18
  68. package/dist/auth/types.d.ts +10 -1
  69. package/dist/bun-oauth.js +4 -0
  70. package/dist/cli.js +3 -1
  71. package/dist/compat.js +17 -14
  72. package/dist/env-api-keys.js +2 -0
  73. package/dist/image-models.d.ts +19 -8
  74. package/dist/image-models.js +14 -13
  75. package/dist/images-api-registry.d.ts +8 -8
  76. package/dist/images.d.ts +7 -2
  77. package/dist/images.js +5 -0
  78. package/dist/index.d.ts +2 -2
  79. package/dist/index.js +2 -2
  80. package/dist/model-catalog.d.ts +27 -9
  81. package/dist/model-catalog.js +24 -2
  82. package/dist/model.d.ts +13 -13
  83. package/dist/models-store.d.ts +3 -2
  84. package/dist/models.d.ts +106 -36
  85. package/dist/models.generated.d.ts +142 -42
  86. package/dist/models.generated.js +142 -42
  87. package/dist/models.js +174 -36
  88. package/dist/providers/alibaba-token-plan.models.d.ts +4 -2
  89. package/dist/providers/alibaba-token-plan.models.js +4 -2
  90. package/dist/providers/all.d.ts +72 -19
  91. package/dist/providers/all.js +28 -22
  92. package/dist/providers/amazon-bedrock.models.d.ts +4 -2
  93. package/dist/providers/amazon-bedrock.models.js +4 -2
  94. package/dist/providers/ant-ling.models.d.ts +4 -2
  95. package/dist/providers/ant-ling.models.js +4 -2
  96. package/dist/providers/anthropic.models.d.ts +4 -2
  97. package/dist/providers/anthropic.models.js +4 -2
  98. package/dist/providers/azure-openai-responses.models.d.ts +4 -2
  99. package/dist/providers/azure-openai-responses.models.js +4 -2
  100. package/dist/providers/bai.models.d.ts +4 -2
  101. package/dist/providers/bai.models.js +4 -2
  102. package/dist/providers/baseten.models.d.ts +4 -2
  103. package/dist/providers/baseten.models.js +4 -2
  104. package/dist/providers/cerebras.models.d.ts +4 -2
  105. package/dist/providers/cerebras.models.js +4 -2
  106. package/dist/providers/chatgpt-subscription.models.d.ts +4 -2
  107. package/dist/providers/chatgpt-subscription.models.js +4 -2
  108. package/dist/providers/cloudflare-ai-gateway.models.d.ts +4 -2
  109. package/dist/providers/cloudflare-ai-gateway.models.js +4 -2
  110. package/dist/providers/cloudflare-stream.d.ts +6 -2
  111. package/dist/providers/cloudflare-stream.js +6 -0
  112. package/dist/providers/cloudflare-workers-ai.js +10 -3
  113. package/dist/providers/cloudflare-workers-ai.models.d.ts +4 -2
  114. package/dist/providers/cloudflare-workers-ai.models.js +4 -2
  115. package/dist/providers/data/.manifest.json +1 -1
  116. package/dist/providers/data/alibaba-token-plan.json +1 -1
  117. package/dist/providers/data/amazon-bedrock.json +1 -1
  118. package/dist/providers/data/ant-ling.json +1 -1
  119. package/dist/providers/data/anthropic.json +1 -1
  120. package/dist/providers/data/azure-openai-responses.json +1 -1
  121. package/dist/providers/data/bai.json +1 -1
  122. package/dist/providers/data/baseten.json +1 -1
  123. package/dist/providers/data/cerebras.json +1 -1
  124. package/dist/providers/data/chatgpt-subscription.json +1 -1
  125. package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  126. package/dist/providers/data/cloudflare-workers-ai.json +1 -1
  127. package/dist/providers/data/deepseek.json +1 -1
  128. package/dist/providers/data/fireworks.json +1 -1
  129. package/dist/providers/data/github-copilot.json +1 -1
  130. package/dist/providers/data/google-vertex.json +1 -1
  131. package/dist/providers/data/google.json +1 -1
  132. package/dist/providers/data/groq.json +1 -1
  133. package/dist/providers/data/huggingface.json +1 -1
  134. package/dist/providers/data/meta.json +1 -0
  135. package/dist/providers/data/minimax-cn.json +1 -1
  136. package/dist/providers/data/minimax.json +1 -1
  137. package/dist/providers/data/mistral.json +1 -1
  138. package/dist/providers/data/moonshotai-cn.json +1 -1
  139. package/dist/providers/data/moonshotai.json +1 -1
  140. package/dist/providers/data/nvidia.json +1 -1
  141. package/dist/providers/data/openai.json +1 -1
  142. package/dist/providers/data/opencode-go.json +1 -1
  143. package/dist/providers/data/opencode.json +1 -1
  144. package/dist/providers/data/opengateway.json +1 -1
  145. package/dist/providers/data/openrouter.json +1 -1
  146. package/dist/providers/data/qwen-token-plan-cn.json +1 -1
  147. package/dist/providers/data/qwen-token-plan-individual.json +1 -1
  148. package/dist/providers/data/qwen-token-plan.json +1 -1
  149. package/dist/providers/data/radius.json +1 -0
  150. package/dist/providers/data/together.json +1 -1
  151. package/dist/providers/data/typesafe.json +1 -0
  152. package/dist/providers/data/venice.json +1 -1
  153. package/dist/providers/data/vercel-ai-gateway.json +1 -1
  154. package/dist/providers/data/xai.json +1 -1
  155. package/dist/providers/data/xiaomi-token-plan-ams.json +1 -1
  156. package/dist/providers/data/xiaomi-token-plan-cn.json +1 -1
  157. package/dist/providers/data/xiaomi-token-plan-sgp.json +1 -1
  158. package/dist/providers/data/xiaomi.json +1 -1
  159. package/dist/providers/data/zai-coding-cn.json +1 -1
  160. package/dist/providers/data/zai.json +1 -1
  161. package/dist/providers/deepseek.models.d.ts +4 -2
  162. package/dist/providers/deepseek.models.js +4 -2
  163. package/dist/providers/faux.d.ts +7 -2
  164. package/dist/providers/faux.js +31 -22
  165. package/dist/providers/fireworks.models.d.ts +4 -2
  166. package/dist/providers/fireworks.models.js +4 -2
  167. package/dist/providers/github-copilot.models.d.ts +4 -2
  168. package/dist/providers/github-copilot.models.js +4 -2
  169. package/dist/providers/google-vertex.models.d.ts +4 -2
  170. package/dist/providers/google-vertex.models.js +4 -2
  171. package/dist/providers/google.models.d.ts +4 -2
  172. package/dist/providers/google.models.js +4 -2
  173. package/dist/providers/groq.models.d.ts +4 -2
  174. package/dist/providers/groq.models.js +4 -2
  175. package/dist/providers/huggingface.models.d.ts +4 -2
  176. package/dist/providers/huggingface.models.js +4 -2
  177. package/dist/providers/images/register-builtins.d.ts +2 -2
  178. package/dist/providers/kimi-coding.models.d.ts +54 -7
  179. package/dist/providers/kimi-coding.models.js +34 -7
  180. package/dist/providers/meta.d.ts +3 -0
  181. package/dist/providers/meta.js +24 -0
  182. package/dist/providers/meta.models.d.ts +6 -0
  183. package/dist/providers/meta.models.js +8 -0
  184. package/dist/providers/minimax-cn.models.d.ts +4 -2
  185. package/dist/providers/minimax-cn.models.js +4 -2
  186. package/dist/providers/minimax.models.d.ts +4 -2
  187. package/dist/providers/minimax.models.js +4 -2
  188. package/dist/providers/mistral.models.d.ts +4 -2
  189. package/dist/providers/mistral.models.js +4 -2
  190. package/dist/providers/moonshotai-cn.models.d.ts +4 -2
  191. package/dist/providers/moonshotai-cn.models.js +4 -2
  192. package/dist/providers/moonshotai.models.d.ts +4 -2
  193. package/dist/providers/moonshotai.models.js +4 -2
  194. package/dist/providers/nvidia.models.d.ts +4 -2
  195. package/dist/providers/nvidia.models.js +4 -2
  196. package/dist/providers/openai.js +4 -2
  197. package/dist/providers/openai.models.d.ts +4 -2
  198. package/dist/providers/openai.models.js +4 -2
  199. package/dist/providers/opencode-go.models.d.ts +4 -2
  200. package/dist/providers/opencode-go.models.js +4 -2
  201. package/dist/providers/opencode.d.ts +3 -1
  202. package/dist/providers/opencode.js +5 -2
  203. package/dist/providers/opencode.models.d.ts +4 -2
  204. package/dist/providers/opencode.models.js +4 -2
  205. package/dist/providers/opengateway.models.d.ts +4 -2
  206. package/dist/providers/opengateway.models.js +4 -2
  207. package/dist/providers/openrouter.js +11 -2
  208. package/dist/providers/openrouter.models.d.ts +4 -2
  209. package/dist/providers/openrouter.models.js +4 -2
  210. package/dist/providers/qwen-token-plan-cn.models.d.ts +4 -2
  211. package/dist/providers/qwen-token-plan-cn.models.js +4 -2
  212. package/dist/providers/qwen-token-plan-individual.models.d.ts +4 -2
  213. package/dist/providers/qwen-token-plan-individual.models.js +4 -2
  214. package/dist/providers/qwen-token-plan.models.d.ts +4 -2
  215. package/dist/providers/qwen-token-plan.models.js +4 -2
  216. package/dist/providers/radius.js +19 -5
  217. package/dist/providers/radius.models.d.ts +6 -0
  218. package/dist/providers/radius.models.js +8 -0
  219. package/dist/providers/together.models.d.ts +4 -2
  220. package/dist/providers/together.models.js +4 -2
  221. package/dist/providers/typesafe.d.ts +3 -0
  222. package/dist/providers/typesafe.js +18 -0
  223. package/dist/providers/typesafe.models.d.ts +6 -0
  224. package/dist/providers/typesafe.models.js +8 -0
  225. package/dist/providers/venice.models.d.ts +4 -2
  226. package/dist/providers/venice.models.js +4 -2
  227. package/dist/providers/vercel-ai-gateway.js +5 -2
  228. package/dist/providers/vercel-ai-gateway.models.d.ts +4 -2
  229. package/dist/providers/vercel-ai-gateway.models.js +4 -2
  230. package/dist/providers/xai.models.d.ts +4 -2
  231. package/dist/providers/xai.models.js +4 -2
  232. package/dist/providers/xiaomi-token-plan-ams.models.d.ts +4 -2
  233. package/dist/providers/xiaomi-token-plan-ams.models.js +4 -2
  234. package/dist/providers/xiaomi-token-plan-cn.models.d.ts +4 -2
  235. package/dist/providers/xiaomi-token-plan-cn.models.js +4 -2
  236. package/dist/providers/xiaomi-token-plan-sgp.models.d.ts +4 -2
  237. package/dist/providers/xiaomi-token-plan-sgp.models.js +4 -2
  238. package/dist/providers/xiaomi.models.d.ts +4 -2
  239. package/dist/providers/xiaomi.models.js +4 -2
  240. package/dist/providers/zai-coding-cn.models.d.ts +4 -2
  241. package/dist/providers/zai-coding-cn.models.js +4 -2
  242. package/dist/providers/zai.models.d.ts +4 -2
  243. package/dist/providers/zai.models.js +4 -2
  244. package/dist/tool-call-middleware/context-transformer.d.ts +8 -5
  245. package/dist/tool-call-middleware/context-transformer.js +44 -15
  246. package/dist/types.d.ts +262 -28
  247. package/dist/utils/diagnostics.d.ts +3 -2
  248. package/dist/utils/estimate.d.ts +2 -2
  249. package/dist/utils/estimate.js +22 -30
  250. package/dist/utils/headers.d.ts +1 -1
  251. package/dist/utils/headers.js +10 -8
  252. package/dist/utils/model-operations.d.ts +11 -0
  253. package/dist/utils/model-operations.js +47 -0
  254. package/dist/utils/models-error.d.ts +8 -0
  255. package/dist/utils/models-error.js +18 -0
  256. package/dist/utils/overflow.d.ts +1 -0
  257. package/dist/utils/overflow.js +11 -5
  258. package/dist/utils/prompt-cache-ttl.js +10 -3
  259. package/dist/utils/retry.js +9 -0
  260. package/dist/utils/text.d.ts +9 -1
  261. package/dist/utils/text.js +26 -0
  262. package/dist/utils/transcript.d.ts +85 -0
  263. package/dist/utils/transcript.js +205 -0
  264. package/package.json +3 -4
  265. package/dist/image-models.generated.d.ts +0 -925
  266. package/dist/image-models.generated.js +0 -927
  267. package/dist/images-models.d.ts +0 -95
  268. package/dist/images-models.js +0 -141
  269. package/dist/providers/openai-images.d.ts +0 -3
  270. package/dist/providers/openai-images.js +0 -16
  271. package/dist/providers/openrouter-images.d.ts +0 -3
  272. package/dist/providers/openrouter-images.js +0 -22
  273. /package/dist/{auth/oauth → utils}/oauth-page.d.ts +0 -0
  274. /package/dist/{auth/oauth → utils}/oauth-page.js +0 -0
@@ -0,0 +1,47 @@
1
+ import { ModelsError } from "./models-error.js";
2
+ /** The type of a model. Models without `type` are chat models. */
3
+ export function getModelType(model) {
4
+ return model.type ?? "chat";
5
+ }
6
+ /** Runtime-checked model type narrowing, including legacy chat models without `type`. */
7
+ export function isModelType(model, type) {
8
+ return getModelType(model) === type;
9
+ }
10
+ export function assertChatModel(model) {
11
+ if (!isModelType(model, "chat")) {
12
+ throw new ModelsError("provider", `Model ${model.provider}/${model.id} is not a chat model`);
13
+ }
14
+ }
15
+ export function assertImageModel(model) {
16
+ if (!isModelType(model, "image")) {
17
+ throw new ModelsError("provider", `Model ${model.provider}/${model.id} is not an image model`);
18
+ }
19
+ }
20
+ export function assertClassifierModel(model) {
21
+ if (!isModelType(model, "classifier")) {
22
+ throw new ModelsError("provider", `Model ${model.provider}/${model.id} is not a classifier model`);
23
+ }
24
+ }
25
+ export function imageErrorResult(model, error, aborted = false) {
26
+ return {
27
+ api: model.api,
28
+ provider: model.provider,
29
+ model: model.id,
30
+ output: [],
31
+ stopReason: aborted ? "aborted" : "error",
32
+ errorMessage: error instanceof Error ? error.message : String(error),
33
+ timestamp: Date.now(),
34
+ };
35
+ }
36
+ export function classifierErrorResult(model, error, aborted = false) {
37
+ return {
38
+ api: model.api,
39
+ provider: model.provider,
40
+ model: model.id,
41
+ answers: {},
42
+ stopReason: aborted ? "aborted" : "error",
43
+ errorMessage: error instanceof Error ? error.message : String(error),
44
+ timestamp: Date.now(),
45
+ };
46
+ }
47
+ //# sourceMappingURL=model-operations.js.map
@@ -0,0 +1,8 @@
1
+ export type ModelsErrorCode = "model_source" | "model_validation" | "provider" | "stream" | "auth" | "oauth";
2
+ export declare class ModelsError extends Error {
3
+ readonly code: ModelsErrorCode;
4
+ constructor(code: ModelsErrorCode, message: string, options?: {
5
+ cause?: unknown;
6
+ });
7
+ }
8
+ //# sourceMappingURL=models-error.d.ts.map
@@ -0,0 +1,18 @@
1
+ import { formatThrownValue } from "./diagnostics.js";
2
+ export class ModelsError extends Error {
3
+ constructor(code, message, options) {
4
+ super(withCauseDetail(message, options?.cause), options);
5
+ this.name = "ModelsError";
6
+ this.code = code;
7
+ }
8
+ }
9
+ /** Callers surface `error.message` only, so keep the underlying reason in it. */
10
+ function withCauseDetail(message, cause) {
11
+ if (cause === undefined || cause === null)
12
+ return message;
13
+ const detail = formatThrownValue(cause).trim();
14
+ if (!detail || message.includes(detail))
15
+ return message;
16
+ return `${message}: ${detail}`;
17
+ }
18
+ //# sourceMappingURL=models-error.js.map
@@ -28,6 +28,7 @@ import type { AssistantMessage } from "../types.ts";
28
28
  * - Kimi For Coding: "exceeded model token limit: X (requested: Y)"
29
29
  * - DS4: "Prompt has X tokens, but the configured context size is Y tokens"
30
30
  * - DashScope/Qwen: "Range of input length should be [1, X]"
31
+ * - z.ai: "Prompt too long"
31
32
  *
32
33
  * **Unreliable detection:**
33
34
  * - z.ai: Sometimes accepts overflow silently (detectable via usage.input > contextWindow),
@@ -29,7 +29,7 @@
29
29
  * - kiro-lb gateways: "Request payload is 1095225 bytes, over the 1085435 byte limit Kiro accepts." / "Request payload is N tokens, over the M token limit Kiro accepts." (HTTP 400 local payload guard)
30
30
  * - Kiro upstream via kiro-lb: "Model context limit reached. Conversation size exceeds model capacity." (CONTENT_LENGTH_EXCEEDS_THRESHOLD token overflow)
31
31
  * - Mistral: "Prompt contains X tokens ... too large for model with Y maximum context length"
32
- * - z.ai: Does NOT error, accepts overflow silently - handled via usage.input > contextWindow
32
+ * - z.ai: `{"code":"1261","message":"Prompt too long"}` or silent overflow via usage.input > contextWindow
33
33
  * - Xiaomi MiMo: Truncates input to fill contextWindow exactly, then returns finish_reason "length"
34
34
  * with output=0 (no room left to generate). Detected via stopReason "length" + zero output +
35
35
  * input filling the context window.
@@ -41,7 +41,7 @@
41
41
  const OVERFLOW_PATTERNS = [
42
42
  /^Context window exhausted: /, // pi-ai pre-flight guard: no answer room left, provider never called
43
43
  /^The conversation is too long to resend \(about \d+ tokens, limit \d+\)/, // anthropic-subscription cold-seed budget: re-send refused before dispatch
44
- /prompt is too long/i, // Anthropic token overflow
44
+ /prompt (?:is )?too long/i, // Anthropic and z.ai token overflow
45
45
  /request_too_large/i, // Anthropic request byte-size overflow (HTTP 413)
46
46
  /input is too long for requested model/i, // Amazon Bedrock
47
47
  /exceeds (?:(?:the|this) )?(?:model'?s )?context window/i, // OpenAI (Completions & Responses API)
@@ -65,11 +65,11 @@ const OVERFLOW_PATTERNS = [
65
65
  /context[_ ]length[_ ]exceeded/i, // Generic fallback
66
66
  /too many tokens/i, // Generic fallback
67
67
  /token limit exceeded/i, // Generic fallback
68
- /^4(?:00|13)\s*(?:status code)?\s*\(no body\)/i, // Cerebras: 400/413 with no body
69
68
  /(?:request[ _])?(?:body|entity|payload)[_ ]too[_ ]large/i, // Gateway HTTP 413 byte-size rejections ("Request body too large", "Request Entity Too Large", "body_too_large", "Payload Too Large"). Substring-anchored by design (JSON bodies lack an adjacent status code); a non-context size rejection (e.g. an oversized image) can over-match, which costs one bounded shrink-retry, never a wedge.
70
69
  /Request payload is \d+ (?:bytes, over the \d+ byte|tokens, over the \d+ token) limit Kiro accepts\./, // kiro-lb local byte/token payload guard (HTTP 400; Anthropic uses invalid_request_error, OpenAI uses detail).
71
70
  /Model context limit reached\. Conversation size exceeds model capacity\./, // kiro-lb enhancement of Kiro CONTENT_LENGTH_EXCEEDS_THRESHOLD
72
71
  ];
72
+ const CEREBRAS_BODYLESS_OVERFLOW_PATTERN = /^4(?:00|13)\s*(?:status code)?\s*\(no body\)/i;
73
73
  /**
74
74
  * Patterns that indicate non-overflow errors (e.g. rate limiting, server errors).
75
75
  * Error messages matching any of these are excluded from overflow detection
@@ -133,6 +133,7 @@ const RESOURCE_EXHAUSTED_PATTERN = /resource.?exhausted/i;
133
133
  * - Kimi For Coding: "exceeded model token limit: X (requested: Y)"
134
134
  * - DS4: "Prompt has X tokens, but the configured context size is Y tokens"
135
135
  * - DashScope/Qwen: "Range of input length should be [1, X]"
136
+ * - z.ai: "Prompt too long"
136
137
  *
137
138
  * **Unreliable detection:**
138
139
  * - z.ai: Sometimes accepts overflow silently (detectable via usage.input > contextWindow),
@@ -163,8 +164,13 @@ export function isContextOverflow(message, contextWindow) {
163
164
  if (message.stopReason === "error" && message.errorMessage) {
164
165
  // Skip messages matching known non-overflow patterns (e.g. throttling / rate-limit)
165
166
  const isNonOverflow = NON_OVERFLOW_PATTERNS.some((p) => p.test(message.errorMessage));
166
- if (!isNonOverflow && OVERFLOW_PATTERNS.some((p) => p.test(message.errorMessage))) {
167
- return true;
167
+ if (!isNonOverflow) {
168
+ if (OVERFLOW_PATTERNS.some((p) => p.test(message.errorMessage))) {
169
+ return true;
170
+ }
171
+ if (message.provider === "cerebras" && CEREBRAS_BODYLESS_OVERFLOW_PATTERN.test(message.errorMessage)) {
172
+ return true;
173
+ }
168
174
  }
169
175
  const usage = message.usage;
170
176
  const hasTokenEvidence = (usage.totalTokens || usage.input + usage.output + usage.cacheRead + usage.cacheWrite) > 0;
@@ -70,6 +70,8 @@ export function getAnthropicCompat(model) {
70
70
  unsignedThinkingReplay: model.compat?.unsignedThinkingReplay ?? (model.compat?.allowEmptySignature ? "empty-signature" : "text"),
71
71
  allowedFallbackModels: model.compat?.allowedFallbackModels ?? [],
72
72
  supportsStrictTools: model.compat?.supportsStrictTools ?? false,
73
+ supportsMidConvoSystemMessages: model.compat?.supportsMidConvoSystemMessages ?? false,
74
+ supportsMidConvoToolChanges: model.compat?.supportsMidConvoToolChanges ?? false,
73
75
  supportsToolReferences: model.compat?.supportsToolReferences ?? defaultSupportsToolReferences(model),
74
76
  // Default: first-party Anthropic only. Anthropic-compatible providers
75
77
  // (kimi-coding, fireworks, copilot, gateways) may execute the server-side
@@ -98,10 +100,10 @@ function detectOpenAICompletionsCompat(model) {
98
100
  const isCloudflareAiGateway = provider === "cloudflare-ai-gateway" || baseUrl.includes("gateway.ai.cloudflare.com");
99
101
  const isNvidia = provider === "nvidia" || baseUrl.includes("integrate.api.nvidia.com");
100
102
  const isAntLing = provider === "ant-ling" || baseUrl.includes("api.ant-ling.com");
103
+ const isCerebras = provider === "cerebras" || baseUrl.includes("cerebras.ai");
101
104
  const isDeepSeek = provider === "deepseek" || baseUrl.toLowerCase().includes("deepseek.com");
102
105
  const isNonStandard = isNvidia ||
103
- provider === "cerebras" ||
104
- baseUrl.includes("cerebras.ai") ||
106
+ isCerebras ||
105
107
  provider === "xai" ||
106
108
  baseUrl.includes("api.x.ai") ||
107
109
  isTogether ||
@@ -154,11 +156,14 @@ function detectOpenAICompletionsCompat(model) {
154
156
  vercelGatewayRouting: {},
155
157
  chatTemplateKwargs: {},
156
158
  zaiToolStream: false,
157
- supportsStrictMode: !isMoonshot && !isTogether && !isCloudflareAiGateway && !isNvidia,
159
+ // OpenAI compatibility alone does not imply strict JSON-schema tool support.
160
+ supportsStrictMode: false,
158
161
  toolSchemaFlavor: isMoonshot ? "moonshot-mfjs" : undefined,
159
162
  supportsDisabledThinking: true,
160
163
  toolCallFormat: undefined,
161
164
  supportsOpenAIGrammarTools: false,
165
+ supportsMidConvoSystemMessages: false,
166
+ supportsMidConvoToolAdditions: false,
162
167
  cacheControlFormat,
163
168
  sendSessionAffinityHeaders: isOpenRouter,
164
169
  deferredToolsMode: undefined,
@@ -205,6 +210,8 @@ export function getOpenAICompletionsCompat(model) {
205
210
  toolSchemaFlavor: model.compat.toolSchemaFlavor ?? detected.toolSchemaFlavor,
206
211
  toolCallFormat: model.compat.toolCallFormat ?? detected.toolCallFormat,
207
212
  supportsOpenAIGrammarTools: model.compat.supportsOpenAIGrammarTools ?? detected.supportsOpenAIGrammarTools,
213
+ supportsMidConvoSystemMessages: model.compat.supportsMidConvoSystemMessages ?? detected.supportsMidConvoSystemMessages,
214
+ supportsMidConvoToolAdditions: model.compat.supportsMidConvoToolAdditions ?? detected.supportsMidConvoToolAdditions,
208
215
  cacheControlFormat: model.compat.cacheControlFormat ?? detected.cacheControlFormat,
209
216
  sendSessionAffinityHeaders: model.compat.sendSessionAffinityHeaders ?? detected.sendSessionAffinityHeaders,
210
217
  deferredToolsMode: model.compat.deferredToolsMode ?? detected.deferredToolsMode,
@@ -84,6 +84,9 @@ const NON_RETRYABLE_PROVIDER_ERROR_PATTERN = buildProviderErrorPattern([
84
84
  "tools\\.[^ ]*function\\.parameters",
85
85
  "tools\\.\\d+\\.function\\.parameters",
86
86
  "invalid tool schema",
87
+ // Sign in with ChatGPT: the subscription's shared usage limit, which resets
88
+ // after hours rather than seconds.
89
+ "subscription_sharing_usage_limit_exceeded",
87
90
  ]);
88
91
  const RETRYABLE_PROVIDER_ERROR_PATTERN = buildProviderErrorPattern([
89
92
  // Local credential/auth sidecar lock exhaustion is infrastructure contention,
@@ -91,6 +94,7 @@ const RETRYABLE_PROVIDER_ERROR_PATTERN = buildProviderErrorPattern([
91
94
  "Credential store is busy: lock",
92
95
  // Generic provider load, HTTP status, and server-side transient failures.
93
96
  "overloaded",
97
+ "currently experiencing high demand",
94
98
  "rate.?limit",
95
99
  "too many requests",
96
100
  "429",
@@ -98,6 +102,7 @@ const RETRYABLE_PROVIDER_ERROR_PATTERN = buildProviderErrorPattern([
98
102
  "502",
99
103
  "503",
100
104
  "504",
105
+ "520",
101
106
  // Cloudflare 522 (Connection timed out): origin stopped responding; transient
102
107
  // like the other 5xx gateway statuses, surfaced as "Error: error code: 522".
103
108
  "522",
@@ -192,6 +197,10 @@ const RETRYABLE_PROVIDER_ERROR_PATTERN = buildProviderErrorPattern([
192
197
  // hits proper-lockfile while the previous subprocess still holds the file.
193
198
  // Same-process retry recovers; hopping providers cannot release that lock.
194
199
  "Lock file is already being held",
200
+ // Sign in with ChatGPT: usage or user data temporarily unavailable. Usage
201
+ // failures can arrive mid-stream without an HTTP 503 in the message.
202
+ "subscription_sharing_usage_unavailable",
203
+ "subscription_sharing_user_unavailable",
195
204
  ]);
196
205
  export const DEFAULT_MAX_AGENT_RETRY_DELAY_MS = 60_000;
197
206
  /**
@@ -1,6 +1,14 @@
1
- import type { ImageContent, ProviderNativeContent, TextContent, ThinkingContent, ToolCall } from "../types.ts";
1
+ import type { ImageContent, ProviderNativeContent, SystemMessage, TextContent, ThinkingContent, ToolCall } from "../types.ts";
2
2
  type Content = TextContent | ImageContent | ThinkingContent | ToolCall | ProviderNativeContent;
3
3
  /** Extract and join text from message content. */
4
4
  export declare function contentText(content: string | readonly Content[], separator?: string): string;
5
+ /** Render a system message as a complete prompt: its content followed by its sections. */
6
+ export declare function getSystemMessageText(message: SystemMessage): string;
7
+ /**
8
+ * Render a later system message for APIs that accept system messages mid-conversation.
9
+ * Section changes are framed by name so the model can relate them to the leading prompt.
10
+ * This framing is request-time only and may change between versions.
11
+ */
12
+ export declare function renderSystemMessageUpdate(message: SystemMessage): string;
5
13
  export {};
6
14
  //# sourceMappingURL=text.d.ts.map
@@ -7,4 +7,30 @@ export function contentText(content, separator = "\n") {
7
7
  .map((block) => block.text)
8
8
  .join(separator);
9
9
  }
10
+ /** Render a system message as a complete prompt: its content followed by its sections. */
11
+ export function getSystemMessageText(message) {
12
+ const parts = [contentText(message.content)];
13
+ for (const text of Object.values(message.sections ?? {})) {
14
+ if (text !== null)
15
+ parts.push(text);
16
+ }
17
+ return parts.filter((part) => part.length > 0).join("\n\n");
18
+ }
19
+ /**
20
+ * Render a later system message for APIs that accept system messages mid-conversation.
21
+ * Section changes are framed by name so the model can relate them to the leading prompt.
22
+ * This framing is request-time only and may change between versions.
23
+ */
24
+ export function renderSystemMessageUpdate(message) {
25
+ const parts = [];
26
+ const text = contentText(message.content);
27
+ if (text.length > 0)
28
+ parts.push(text);
29
+ for (const [name, value] of Object.entries(message.sections ?? {})) {
30
+ parts.push(value === null
31
+ ? `Removed system prompt section "${name}".`
32
+ : `Updated system prompt section "${name}":\n\n${value}`);
33
+ }
34
+ return parts.join("\n\n");
35
+ }
10
36
  //# sourceMappingURL=text.js.map
@@ -0,0 +1,85 @@
1
+ import type { Context, Message, SystemMessage, Tool, ToolReference, TranscriptContext } from "../types.ts";
2
+ export type { TranscriptContext } from "../types.ts";
3
+ /**
4
+ * Build the leading system message for a prompt and tool set. Returns undefined when
5
+ * both are empty, so an empty transcript stays empty.
6
+ */
7
+ export declare function createInitialSystemMessage(systemPrompt: string | undefined, tools: Tool[] | undefined): SystemMessage | undefined;
8
+ /**
9
+ * Fold `Context.systemPrompt` and `Context.tools` into a leading system message.
10
+ * This is the only entry point that produces a {@link TranscriptContext}; every
11
+ * provider-facing function expects the result. `Context.activeToolNames` is carried
12
+ * over unchanged (senpi#2095 allowed-tools): it has no system-message representation.
13
+ */
14
+ export declare function normalizeContext(context: Context): TranscriptContext;
15
+ /**
16
+ * Any message list. The replay helpers only read entries whose role is `"system"`, so
17
+ * agent transcripts that carry custom message roles can be passed without filtering.
18
+ */
19
+ export type TranscriptMessages = readonly {
20
+ role: string;
21
+ }[];
22
+ /** Return the leading system message, if the transcript starts with one. */
23
+ export declare function getInitialSystemMessage(messages: TranscriptMessages): SystemMessage | undefined;
24
+ /** Drop the leading system message for APIs that carry the prompt outside the message list. */
25
+ export declare function withoutInitialSystemMessage(messages: Message[]): Message[];
26
+ /** Resolve the tools available after applying every transcript delta in order. */
27
+ export declare function getCurrentTools(messages: TranscriptMessages): Tool[];
28
+ /**
29
+ * Replay every system message into one leading system message holding the current
30
+ * prompt and tools. Later `content` is appended to the base prompt, `sections` are
31
+ * patched by name, and tools are resolved with {@link getCurrentTools}.
32
+ */
33
+ export declare function getCurrentSystemMessage(messages: TranscriptMessages): SystemMessage | undefined;
34
+ /** Render the current system prompt text after replaying every system message. */
35
+ export declare function getCurrentSystemPrompt(messages: TranscriptMessages): string;
36
+ /**
37
+ * Rebuild the transcript for APIs without mid-conversation system messages: the replayed
38
+ * system message leads, and every later system message is dropped.
39
+ */
40
+ export declare function collapseSystemMessages(context: TranscriptContext): TranscriptContext;
41
+ /** Keep later system messages in place when the model accepts them; otherwise collapse them. */
42
+ export declare function resolveTranscript(context: TranscriptContext, supportsMidConvoSystemMessages: boolean | undefined): TranscriptContext;
43
+ /** Strip executable and display-only fields from a tool before transcript comparison or persistence. */
44
+ export declare function toToolDeclaration(tool: Tool): Tool;
45
+ /**
46
+ * Whether two tools declare the same interface to the model.
47
+ *
48
+ * Both sides go through {@link toToolDeclaration} first: its JSON round-trip drops the
49
+ * typebox symbol keys and `undefined` fields that a structural comparison would see, and
50
+ * builds both objects with the same key order, so comparing the serialized declarations
51
+ * is exact. This avoids a deep-equal dependency in a browser-safe package.
52
+ */
53
+ export declare function declarationsEqual(left: Tool, right: Tool): boolean;
54
+ export interface ToolStateChanges {
55
+ toolsAdded: Tool[];
56
+ toolsRemoved: ToolReference[];
57
+ }
58
+ /** Compare two complete tool states. A changed definition is a removal followed by an addition. */
59
+ export declare function getToolStateChanges(previous: readonly Tool[], current: readonly Tool[]): ToolStateChanges;
60
+ /** Every definition referenced by transcript tool state, in first-declaration order. */
61
+ export declare function getDeclaredTools(messages: TranscriptMessages): Tool[];
62
+ /**
63
+ * Whether a tool name was declared twice with different definitions. Transports that
64
+ * reference tools by name (Anthropic `tool_addition`/`tool_removal`) cannot express that.
65
+ */
66
+ export declare function hasToolRedefinitions(messages: TranscriptMessages): boolean;
67
+ /** Whether tool history contains a removal or same-name redeclaration that an addition-only transport cannot replay. */
68
+ export declare function hasNonAdditiveToolChanges(messages: TranscriptMessages): boolean;
69
+ export interface TranscriptTools {
70
+ /** Tools sent in the top-level request field. */
71
+ requestTools: Tool[];
72
+ /**
73
+ * Whether later system messages carry their own `toolsAdded` as in-place additions.
74
+ * When false, `requestTools` already holds the complete current tool set.
75
+ */
76
+ anchorsAdditions: boolean;
77
+ }
78
+ /**
79
+ * Split tool declarations between the top-level request field and in-place additions.
80
+ * Transports that can anchor additions at a system message keep the initial tools at the
81
+ * top and load later ones where they appear; that only works when no tool was removed or
82
+ * redeclared, so everything else sends the current tool list.
83
+ */
84
+ export declare function resolveTranscriptTools(messages: TranscriptMessages, supportsToolAdditions: boolean): TranscriptTools;
85
+ //# sourceMappingURL=transcript.d.ts.map
@@ -0,0 +1,205 @@
1
+ import { contentText, getSystemMessageText } from "./text.js";
2
+ /**
3
+ * Build the leading system message for a prompt and tool set. Returns undefined when
4
+ * both are empty, so an empty transcript stays empty.
5
+ */
6
+ export function createInitialSystemMessage(systemPrompt, tools) {
7
+ const hasSystemPrompt = systemPrompt !== undefined && systemPrompt.length > 0;
8
+ const hasTools = tools !== undefined && tools.length > 0;
9
+ if (!hasSystemPrompt && !hasTools)
10
+ return undefined;
11
+ return {
12
+ role: "system",
13
+ content: systemPrompt ?? "",
14
+ ...(hasTools ? { toolsAdded: tools } : {}),
15
+ timestamp: 0,
16
+ };
17
+ }
18
+ /**
19
+ * Fold `Context.systemPrompt` and `Context.tools` into a leading system message.
20
+ * This is the only entry point that produces a {@link TranscriptContext}; every
21
+ * provider-facing function expects the result. `Context.activeToolNames` is carried
22
+ * over unchanged (senpi#2095 allowed-tools): it has no system-message representation.
23
+ */
24
+ export function normalizeContext(context) {
25
+ const initialMessage = createInitialSystemMessage(context.systemPrompt, context.tools);
26
+ const messages = initialMessage ? [initialMessage, ...context.messages] : context.messages;
27
+ return (context.activeToolNames ? { messages, activeToolNames: context.activeToolNames } : { messages });
28
+ }
29
+ function isSystemMessage(message) {
30
+ return message.role === "system";
31
+ }
32
+ /** Return the leading system message, if the transcript starts with one. */
33
+ export function getInitialSystemMessage(messages) {
34
+ const first = messages[0];
35
+ return first && isSystemMessage(first) ? first : undefined;
36
+ }
37
+ /** Drop the leading system message for APIs that carry the prompt outside the message list. */
38
+ export function withoutInitialSystemMessage(messages) {
39
+ return getInitialSystemMessage(messages) ? messages.slice(1) : messages;
40
+ }
41
+ /** Resolve the tools available after applying every transcript delta in order. */
42
+ export function getCurrentTools(messages) {
43
+ const tools = new Map();
44
+ for (const message of messages) {
45
+ if (!isSystemMessage(message))
46
+ continue;
47
+ for (const tool of message.toolsRemoved ?? [])
48
+ tools.delete(tool.name);
49
+ for (const tool of message.toolsAdded ?? [])
50
+ tools.set(tool.name, tool);
51
+ }
52
+ return [...tools.values()];
53
+ }
54
+ /**
55
+ * Replay every system message into one leading system message holding the current
56
+ * prompt and tools. Later `content` is appended to the base prompt, `sections` are
57
+ * patched by name, and tools are resolved with {@link getCurrentTools}.
58
+ */
59
+ export function getCurrentSystemMessage(messages) {
60
+ const content = [];
61
+ const sections = new Map();
62
+ let timestamp;
63
+ for (const message of messages) {
64
+ if (!isSystemMessage(message))
65
+ continue;
66
+ timestamp ??= message.timestamp;
67
+ const text = contentText(message.content);
68
+ if (text.length > 0)
69
+ content.push(text);
70
+ for (const [name, value] of Object.entries(message.sections ?? {})) {
71
+ if (value === null)
72
+ sections.delete(name);
73
+ else
74
+ sections.set(name, value);
75
+ }
76
+ }
77
+ const tools = getCurrentTools(messages);
78
+ if (timestamp === undefined && tools.length === 0)
79
+ return undefined;
80
+ return {
81
+ role: "system",
82
+ content: content.join("\n\n"),
83
+ ...(sections.size > 0 ? { sections: Object.fromEntries(sections) } : {}),
84
+ ...(tools.length > 0 ? { toolsAdded: tools } : {}),
85
+ timestamp: timestamp ?? 0,
86
+ };
87
+ }
88
+ /** Render the current system prompt text after replaying every system message. */
89
+ export function getCurrentSystemPrompt(messages) {
90
+ const message = getCurrentSystemMessage(messages);
91
+ return message ? getSystemMessageText(message) : "";
92
+ }
93
+ /**
94
+ * Rebuild the transcript for APIs without mid-conversation system messages: the replayed
95
+ * system message leads, and every later system message is dropped.
96
+ */
97
+ export function collapseSystemMessages(context) {
98
+ const head = getCurrentSystemMessage(context.messages);
99
+ const messages = context.messages.filter((message) => message.role !== "system");
100
+ return { ...context, messages: head ? [head, ...messages] : messages };
101
+ }
102
+ /** Keep later system messages in place when the model accepts them; otherwise collapse them. */
103
+ export function resolveTranscript(context, supportsMidConvoSystemMessages) {
104
+ return supportsMidConvoSystemMessages ? context : collapseSystemMessages(context);
105
+ }
106
+ /** Strip executable and display-only fields from a tool before transcript comparison or persistence. */
107
+ export function toToolDeclaration(tool) {
108
+ return {
109
+ name: tool.name,
110
+ description: tool.description,
111
+ parameters: JSON.parse(JSON.stringify(tool.parameters)),
112
+ ...(tool.constrainedSampling === undefined ? {} : { constrainedSampling: tool.constrainedSampling }),
113
+ };
114
+ }
115
+ /**
116
+ * Whether two tools declare the same interface to the model.
117
+ *
118
+ * Both sides go through {@link toToolDeclaration} first: its JSON round-trip drops the
119
+ * typebox symbol keys and `undefined` fields that a structural comparison would see, and
120
+ * builds both objects with the same key order, so comparing the serialized declarations
121
+ * is exact. This avoids a deep-equal dependency in a browser-safe package.
122
+ */
123
+ export function declarationsEqual(left, right) {
124
+ return JSON.stringify(toToolDeclaration(left)) === JSON.stringify(toToolDeclaration(right));
125
+ }
126
+ /** Compare two complete tool states. A changed definition is a removal followed by an addition. */
127
+ export function getToolStateChanges(previous, current) {
128
+ const previousTools = new Map(previous.map((tool) => [tool.name, tool]));
129
+ const currentTools = new Map(current.map((tool) => [tool.name, tool]));
130
+ return {
131
+ toolsAdded: current
132
+ .filter((tool) => {
133
+ const previousTool = previousTools.get(tool.name);
134
+ return previousTool === undefined || !declarationsEqual(previousTool, tool);
135
+ })
136
+ .map(toToolDeclaration),
137
+ toolsRemoved: previous
138
+ .filter((tool) => {
139
+ const currentTool = currentTools.get(tool.name);
140
+ return currentTool === undefined || !declarationsEqual(tool, currentTool);
141
+ })
142
+ .map((tool) => ({ name: tool.name })),
143
+ };
144
+ }
145
+ /** Every definition referenced by transcript tool state, in first-declaration order. */
146
+ export function getDeclaredTools(messages) {
147
+ const definitions = new Map();
148
+ for (const message of messages) {
149
+ if (!isSystemMessage(message))
150
+ continue;
151
+ for (const tool of message.toolsAdded ?? [])
152
+ definitions.set(tool.name, tool);
153
+ }
154
+ return [...definitions.values()];
155
+ }
156
+ /**
157
+ * Whether a tool name was declared twice with different definitions. Transports that
158
+ * reference tools by name (Anthropic `tool_addition`/`tool_removal`) cannot express that.
159
+ */
160
+ export function hasToolRedefinitions(messages) {
161
+ const declared = new Map();
162
+ for (const message of messages) {
163
+ if (!isSystemMessage(message))
164
+ continue;
165
+ for (const tool of message.toolsAdded ?? []) {
166
+ const previous = declared.get(tool.name);
167
+ if (previous !== undefined && !declarationsEqual(previous, tool))
168
+ return true;
169
+ declared.set(tool.name, tool);
170
+ }
171
+ }
172
+ return false;
173
+ }
174
+ /** Whether tool history contains a removal or same-name redeclaration that an addition-only transport cannot replay. */
175
+ export function hasNonAdditiveToolChanges(messages) {
176
+ const declared = new Set();
177
+ for (const message of messages) {
178
+ if (!isSystemMessage(message))
179
+ continue;
180
+ if ((message.toolsRemoved?.length ?? 0) > 0)
181
+ return true;
182
+ for (const tool of message.toolsAdded ?? []) {
183
+ if (declared.has(tool.name))
184
+ return true;
185
+ declared.add(tool.name);
186
+ }
187
+ }
188
+ return false;
189
+ }
190
+ /**
191
+ * Split tool declarations between the top-level request field and in-place additions.
192
+ * Transports that can anchor additions at a system message keep the initial tools at the
193
+ * top and load later ones where they appear; that only works when no tool was removed or
194
+ * redeclared, so everything else sends the current tool list.
195
+ */
196
+ export function resolveTranscriptTools(messages, supportsToolAdditions) {
197
+ const anchorsAdditions = supportsToolAdditions && !hasNonAdditiveToolChanges(messages);
198
+ return {
199
+ requestTools: anchorsAdditions
200
+ ? (getInitialSystemMessage(messages)?.toolsAdded ?? [])
201
+ : getCurrentTools(messages),
202
+ anchorsAdditions,
203
+ };
204
+ }
205
+ //# sourceMappingURL=transcript.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi-ai",
3
- "version": "2026.9.30",
3
+ "version": "2026.10.1",
4
4
  "description": "Unified LLM API with automatic model discovery and provider configuration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -73,19 +73,18 @@
73
73
  "generate-models": "tsx scripts/generate-models.ts --strict",
74
74
  "hydrate-model-data": "tsx scripts/generate-models.ts --strict --data-only",
75
75
  "generate-model-catalog": "tsx scripts/generate-models.ts --strict --json-only --json-output ../../.artifacts/model-catalog",
76
- "generate-image-models": "tsx scripts/generate-image-models.ts --strict",
77
76
  "check:model-data": "tsx scripts/check-model-data.ts",
78
77
  "build": "tsgo -p tsconfig.build.json && shx chmod +x dist/cli.js && shx rm -rf dist/providers/data && shx cp -r src/providers/data dist/providers/data",
79
78
  "build:offline": "npm run check:model-data && tsc -p tsconfig.build.json && shx chmod +x dist/cli.js && shx rm -rf dist/providers/data && shx cp -r src/providers/data dist/providers/data",
80
79
  "test": "vitest --run",
81
- "prepublishOnly": "shx rm -rf dist && tsx scripts/generate-models.ts && tsx scripts/generate-image-models.ts && tsc -p tsconfig.build.json && shx chmod +x dist/cli.js",
80
+ "prepublishOnly": "shx rm -rf dist && tsx scripts/generate-models.ts && tsc -p tsconfig.build.json && shx chmod +x dist/cli.js",
82
81
  "dev": "tsc -p tsconfig.build.json --watch --preserveWatchOutput",
83
82
  "dev:tsc": "tsc -p tsconfig.build.json --watch --preserveWatchOutput"
84
83
  },
85
84
  "dependencies": {
86
85
  "@anthropic-ai/sdk": "0.127.0",
87
86
  "@aws-sdk/client-bedrock-runtime": "3.1136.0",
88
- "@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.9.30",
87
+ "@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.10.1",
89
88
  "@google/genai": "2.23.0",
90
89
  "@smithy/node-http-handler": "4.12.1",
91
90
  "http-proxy-agent": "9.1.0",