@prestyj/ai 5.11.0 → 5.13.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/README.md CHANGED
@@ -42,7 +42,7 @@ Tool parameters are Zod schemas. Converted to JSON Schema at the provider bounda
42
42
  |---|---|---|
43
43
  | `anthropic` | Claude Opus 5, Sonnet 5, Haiku 4.5 | Extended thinking, prompt caching, server-side compaction |
44
44
  | `openai` | GPT-4.1, o3, o4-mini | Supports OAuth (codex endpoint) and API keys |
45
- | `glm` | GLM-5.1, GLM-4.7 | Z.AI platform, OpenAI-compatible |
45
+ | `glm` | GLM-5.3 | Z.AI platform, OpenAI-compatible |
46
46
  | `moonshot` | Kimi K3, Kimi K2.7 Code | Moonshot platform, OpenAI-compatible |
47
47
 
48
48
  ---
package/dist/index.cjs CHANGED
@@ -53,6 +53,7 @@ __export(index_exports, {
53
53
  redactText: () => redactText,
54
54
  redactValue: () => redactValue,
55
55
  registerPalsuProvider: () => registerPalsuProvider,
56
+ resolveToolSchema: () => resolveToolSchema,
56
57
  sanitizeMessagesForWire: () => sanitizeMessagesForWire,
57
58
  setProviderDiagnostic: () => setProviderDiagnostic,
58
59
  sliceHead: () => sliceHead,
@@ -1171,6 +1172,9 @@ function toLocalReasoningEffort(level) {
1171
1172
  if (level === "max" || level === "ultra" || level === "xhigh") return "max";
1172
1173
  return level;
1173
1174
  }
1175
+ function toGlmReasoningEffort(level) {
1176
+ return level === "ultra" ? "max" : level;
1177
+ }
1174
1178
  function toOpenAIReasoningEffort(level, model) {
1175
1179
  const effort = level === "max" || level === "ultra" ? "xhigh" : level;
1176
1180
  if (model.startsWith("fugu") && (effort === "low" || effort === "medium")) {
@@ -1226,7 +1230,7 @@ function parseToolArguments(argsJson) {
1226
1230
  var NON_STREAMING_TIMEOUT_MS = 60 * 60 * 1e3;
1227
1231
  var anthropicClientCache = /* @__PURE__ */ new Map();
1228
1232
  function fineGrainedToolStreamingEnabled() {
1229
- const raw = process.env.GG_FINE_GRAINED_TOOL_STREAMING ?? process.env.CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING;
1233
+ const raw = process.env.EZ_FINE_GRAINED_TOOL_STREAMING ?? process.env.CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING;
1230
1234
  if (!raw) return false;
1231
1235
  const v = raw.trim().toLowerCase();
1232
1236
  return v === "1" || v === "true" || v === "yes" || v === "on";
@@ -2040,6 +2044,11 @@ async function* runStream2(options) {
2040
2044
  if (usesThinkingParam) {
2041
2045
  if (options.thinking) {
2042
2046
  params.thinking = { type: "enabled" };
2047
+ if (options.provider === "glm") {
2048
+ params.reasoning_effort = toGlmReasoningEffort(
2049
+ options.thinking
2050
+ );
2051
+ }
2043
2052
  } else {
2044
2053
  params.thinking = { type: "disabled" };
2045
2054
  }
@@ -2091,7 +2100,15 @@ async function* runStream2(options) {
2091
2100
  if (chunk.usage) {
2092
2101
  ({ inputTokens, outputTokens, cacheRead, cacheWrite } = extractOpenAIUsage(chunk.usage));
2093
2102
  }
2094
- if (!choice) continue;
2103
+ if (!choice) {
2104
+ const gatewayError = classifyChoicelessFrame(chunk);
2105
+ if (gatewayError) {
2106
+ throw new ProviderError(providerName, gatewayError.message, {
2107
+ statusCode: gatewayError.statusCode
2108
+ });
2109
+ }
2110
+ continue;
2111
+ }
2095
2112
  if (choice.finish_reason) {
2096
2113
  finishReason = choice.finish_reason;
2097
2114
  }
@@ -2275,6 +2292,31 @@ function completionToResponse(completion, endpointKey) {
2275
2292
  }
2276
2293
  };
2277
2294
  }
2295
+ function classifyChoicelessFrame(frame) {
2296
+ if (!frame || typeof frame !== "object" || Array.isArray(frame)) return null;
2297
+ const rec = frame;
2298
+ if (Array.isArray(rec.choices)) return null;
2299
+ const statusOf = (value) => {
2300
+ const n = typeof value === "string" ? Number(value) : value;
2301
+ return typeof n === "number" && Number.isFinite(n) && n >= 400 && n <= 599 ? n : void 0;
2302
+ };
2303
+ const statusCode = statusOf(rec.status) ?? statusOf(rec.statusCode) ?? statusOf(rec.code);
2304
+ const typeIsError = typeof rec.type === "string" && rec.type.toLowerCase() === "error";
2305
+ let detailText;
2306
+ const detail = rec.detail;
2307
+ if (typeof detail === "string" && detail.trim()) {
2308
+ detailText = detail.trim();
2309
+ } else if (Array.isArray(detail)) {
2310
+ const parts = detail.map(
2311
+ (d) => d && typeof d === "object" && typeof d.msg === "string" ? d.msg : typeof d === "string" ? d : ""
2312
+ ).filter(Boolean);
2313
+ if (parts.length) detailText = parts.join("; ");
2314
+ }
2315
+ if (statusCode === void 0 && !typeIsError && !detailText) return null;
2316
+ const rawMessage = (typeof rec.message === "string" && rec.message.trim() ? rec.message.trim() : void 0) ?? detailText ?? (typeof rec.error === "string" && rec.error.trim() ? rec.error.trim() : void 0) ?? (statusCode !== void 0 ? `Gateway returned status ${statusCode}.` : "Gateway error.");
2317
+ const message = rawMessage.slice(0, 500);
2318
+ return { message, statusCode };
2319
+ }
2278
2320
  function classifyOpenAICompatLimit(args) {
2279
2321
  const { status, code, type, message } = args;
2280
2322
  const codeType = `${code ?? ""} ${type ?? ""}`.toLowerCase();
@@ -2286,6 +2328,7 @@ function classifyOpenAICompatLimit(args) {
2286
2328
  return null;
2287
2329
  }
2288
2330
  function toError2(err, provider = "openai") {
2331
+ if (err instanceof ProviderError) return err;
2289
2332
  if (err instanceof import_openai.default.APIError) {
2290
2333
  const body = err.error;
2291
2334
  const bodyMessage = typeof body?.message === "string" && body.message.trim() ? body.message.trim() : void 0;
@@ -3646,6 +3689,8 @@ function sanitizeMessagesForWire(messages) {
3646
3689
  // src/stream.ts
3647
3690
  var GLM_CODING_BASE_URL = "https://api.z.ai/api/coding/paas/v4";
3648
3691
  var KIMI_CODE_USER_AGENT = `kimi-code-cli/${process.env.KIMI_CODE_VERSION ?? "1.0.11"}`;
3692
+ var GROK_CLI_PROXY_HOST = "cli-chat-proxy.grok.com";
3693
+ var GROK_CLI_VERSION = process.env.GROK_CLI_VERSION ?? "0.2.101";
3649
3694
  providerRegistry.register("anthropic", {
3650
3695
  stream: (options) => streamAnthropic(options)
3651
3696
  });
@@ -3712,13 +3757,25 @@ providerRegistry.register("xai", {
3712
3757
  // xAI's public API (console.x.ai key) is OpenAI-compatible — ride the Chat
3713
3758
  // Completions transport like Moonshot/DeepSeek. Grok reasoning models take
3714
3759
  // top-level `reasoning_effort` (low/medium/high), which the shared thinking
3715
- // path already sends. xAI's OAuth path exists but only via the Grok CLI's
3716
- // private Responses proxy (cli-chat-proxy.grok.com) with reverse-engineered
3717
- // attribution headers and account-tier gating — intentionally not wired.
3718
- stream: (options) => streamOpenAI({
3719
- ...options,
3720
- baseUrl: options.baseUrl ?? "https://api.x.ai/v1"
3721
- })
3760
+ // path already sends.
3761
+ //
3762
+ // Subscription OAuth (SuperGrok / X Premium) routes to the Grok CLI chat proxy
3763
+ // instead, which speaks the same Chat Completions wire but gates on Grok-CLI
3764
+ // client identity. Inject those headers centrally here — exactly as the Kimi
3765
+ // endpoint above — so EVERY stream (agent loop, compaction, title-gen,
3766
+ // sub-agents) is accepted rather than depending on each call site to thread
3767
+ // headers. Caller-provided headers still win on collision.
3768
+ stream: (options) => {
3769
+ const baseUrl = options.baseUrl ?? "https://api.x.ai/v1";
3770
+ const defaultHeaders = baseUrl.includes(GROK_CLI_PROXY_HOST) ? {
3771
+ "X-XAI-Token-Auth": "xai-grok-cli",
3772
+ "x-grok-client-version": GROK_CLI_VERSION,
3773
+ "x-grok-client-identifier": "ezcoder",
3774
+ "x-grok-model-override": options.model,
3775
+ ...options.defaultHeaders
3776
+ } : options.defaultHeaders;
3777
+ return streamOpenAI({ ...options, baseUrl, defaultHeaders });
3778
+ }
3722
3779
  });
3723
3780
  providerRegistry.register("minimax", {
3724
3781
  stream: (options) => streamAnthropic({
@@ -4181,6 +4238,7 @@ function registerPalsuProvider(config) {
4181
4238
  redactText,
4182
4239
  redactValue,
4183
4240
  registerPalsuProvider,
4241
+ resolveToolSchema,
4184
4242
  sanitizeMessagesForWire,
4185
4243
  setProviderDiagnostic,
4186
4244
  sliceHead,