@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/dist/index.d.cts CHANGED
@@ -314,7 +314,7 @@ declare class StreamResult implements AsyncIterable<StreamEvent> {
314
314
  * Local model ids are namespaced by endpoint (`local/<endpointId>/<rawId>`) so
315
315
  * the same model name served by two machines stays distinct in the registry.
316
316
  * The server only knows the raw id, so strip the routing prefix here — at the
317
- * one place that talks to the wire. Counterpart to gg-core's
317
+ * one place that talks to the wire. Counterpart to @prestyj/core's
318
318
  * `formatLocalModelId`/`parseLocalModelId`.
319
319
  */
320
320
  declare function localWireModelId(id: string): string;
@@ -383,7 +383,7 @@ declare class ProviderRegistryImpl {
383
383
  declare const providerRegistry: ProviderRegistryImpl;
384
384
 
385
385
  /**
386
- * Error model for gg-ai and downstream consumers.
386
+ * Error model for @prestyj/ai and downstream consumers.
387
387
  *
388
388
  * Every error users see should answer one question: "is this me or them?"
389
389
  * That answer drives whether they retry, switch model, log in, or report a
@@ -450,7 +450,7 @@ declare class ProviderError extends EZCoderAIError {
450
450
  * transient per-minute throttle)? These don't clear with a quick retry — the
451
451
  * user has to wait for the window to reset — so callers must surface them as a
452
452
  * hard stop, not silently retry for minutes. Detected from the canonical
453
- * "usage limit reached" message gg-ai stamps onto the ProviderError.
453
+ * "usage limit reached" message @prestyj/ai stamps onto the ProviderError.
454
454
  */
455
455
  declare function isUsageLimitError(err: unknown): boolean;
456
456
  /**
@@ -521,7 +521,7 @@ declare function sliceTail(text: string, chars: number): string;
521
521
  declare function sanitizeMessagesForWire(messages: Message[]): Message[];
522
522
 
523
523
  /**
524
- * Provider-level diagnostic hook. Mirrors the pattern used by gg-agent's
524
+ * Provider-level diagnostic hook. Mirrors the pattern used by @prestyj/agent's
525
525
  * setStreamDiagnostic — the host app wires a callback (typically writing to
526
526
  * a debug log) and providers call `providerDiag(...)` to record interesting
527
527
  * lifecycle events (e.g. raw SSE event types and timings).
@@ -530,6 +530,47 @@ type ProviderDiagnosticFn = (phase: string, data?: Record<string, unknown>) => v
530
530
  /** Register a diagnostic callback for provider-level tracing. */
531
531
  declare function setProviderDiagnostic(fn: ProviderDiagnosticFn | null): void;
532
532
 
533
+ /**
534
+ * Converts a Zod schema to a JSON Schema object suitable for provider tool
535
+ * parameter definitions.
536
+ *
537
+ * Anthropic's `input_schema` validator is strict in two ways:
538
+ *
539
+ * 1. The root must be `type: "object"`. Returns 400 with
540
+ * `tools.N.custom.input_schema.type: Field required` otherwise.
541
+ *
542
+ * 2. The root must NOT contain `oneOf`, `anyOf`, or `allOf`. Returns 400 with
543
+ * `input_schema does not support oneOf, allOf, or anyOf at the top level`.
544
+ *
545
+ * Both rules trip whenever a tool's parameters are defined via
546
+ * `z.discriminatedUnion(...)` or `z.union(...)` — Zod 4's
547
+ * `z.toJSONSchema` emits `{oneOf: [...]}` at the root with no `type`.
548
+ *
549
+ * The fix is to collapse the union into a single flat object schema:
550
+ *
551
+ * - properties = union of all branch properties (later branches win on
552
+ * conflict; that's fine because the model only uses these for hints —
553
+ * Zod's actual `tool.parameters.parse(args)` is the real validator)
554
+ * - required = intersection of branch `required` arrays (a field is only
555
+ * required if EVERY branch requires it)
556
+ * - if the union has a discriminator field (every branch has the same
557
+ * property as a `const`), we replace the discriminator's per-branch
558
+ * `const` with an `enum` listing every literal — the model gets a clear
559
+ * hint of the valid action values without needing oneOf
560
+ *
561
+ * The flattening is lossy for *schema-level* constraints (e.g. "if action=X,
562
+ * then field Y is required") — Zod still enforces those at parse time. For
563
+ * the model's purposes this is identical to a single object with optional
564
+ * fields and a discriminator enum, which is exactly how Anthropic-supported
565
+ * tools are typically authored anyway.
566
+ */
567
+ type JsonSchema = Record<string, unknown>;
568
+ /**
569
+ * Resolve a tool's JSON Schema for provider tool definitions: prefer the
570
+ * tool's pre-built `rawInputSchema`, otherwise convert its Zod `parameters`.
571
+ */
572
+ declare function resolveToolSchema(tool: Tool): JsonSchema;
573
+
533
574
  /**
534
575
  * Cap historical images before provider dispatch, removing the oldest first.
535
576
  * The persisted/live conversation is never mutated; only modified messages and
@@ -642,4 +683,4 @@ interface PalsuProviderConfig {
642
683
  */
643
684
  declare function registerPalsuProvider(config?: PalsuProviderConfig): PalsuProviderHandle;
644
685
 
645
- export { type AssistantMessage, type CacheRetention, type ContentPart, type DoneEvent, EZCoderAIError, type ErrorEvent, type ErrorSource, EventStream, type FormattedError, type ImageContent, type Message, type MessageProvenance, type MessageProvenanceKind, type MessageProvenanceSource, type MessageProvenanceVisibility, type PalsuModelConfig, type PalsuModelHandle, type PalsuProviderConfig, type PalsuProviderHandle, type PalsuProviderState, type PalsuResponse, type PalsuResponseFactory, type Provider, type ProviderDiagnosticFn, type ProviderEntry, ProviderError, type ProviderStreamFn, REDACTED as REDACTION_MARKER, type RawContent, type RedactionOptions, type ServerToolCall, type ServerToolCallEvent, type ServerToolDefinition, type ServerToolResult, type ServerToolResultEvent, type StopReason, type StreamEvent, type StreamOptions, type StreamResponse, StreamResult, type SystemMessage, type TextContent, type TextDeltaEvent, type ThinkingContent, type ThinkingDeltaEvent, type ThinkingLevel, type Tool, type ToolCall, type ToolCallDeltaEvent, type ToolCallDoneEvent, type ToolChoice, type ToolResult, type ToolResultContent, type ToolResultMessage, type Usage, type UserMessage, type VideoContent, clampProviderContextImages, classifyProviderError, environmentSecrets, formatError, formatErrorForDisplay, hasLoneSurrogate, isHardBillingMessage, isUsageLimitError, localWireModelId, palsuAssistantMessage, palsuText, palsuThinking, palsuToolCall, prewarmAnthropicCache, providerRegistry, redactText, redactValue, registerPalsuProvider, sanitizeMessagesForWire, setProviderDiagnostic, sliceHead, sliceTail, stream, toAnthropicMessages, toOpenAIMessages, toWellFormedText };
686
+ export { type AssistantMessage, type CacheRetention, type ContentPart, type DoneEvent, EZCoderAIError, type ErrorEvent, type ErrorSource, EventStream, type FormattedError, type ImageContent, type Message, type MessageProvenance, type MessageProvenanceKind, type MessageProvenanceSource, type MessageProvenanceVisibility, type PalsuModelConfig, type PalsuModelHandle, type PalsuProviderConfig, type PalsuProviderHandle, type PalsuProviderState, type PalsuResponse, type PalsuResponseFactory, type Provider, type ProviderDiagnosticFn, type ProviderEntry, ProviderError, type ProviderStreamFn, REDACTED as REDACTION_MARKER, type RawContent, type RedactionOptions, type ServerToolCall, type ServerToolCallEvent, type ServerToolDefinition, type ServerToolResult, type ServerToolResultEvent, type StopReason, type StreamEvent, type StreamOptions, type StreamResponse, StreamResult, type SystemMessage, type TextContent, type TextDeltaEvent, type ThinkingContent, type ThinkingDeltaEvent, type ThinkingLevel, type Tool, type ToolCall, type ToolCallDeltaEvent, type ToolCallDoneEvent, type ToolChoice, type ToolResult, type ToolResultContent, type ToolResultMessage, type Usage, type UserMessage, type VideoContent, clampProviderContextImages, classifyProviderError, environmentSecrets, formatError, formatErrorForDisplay, hasLoneSurrogate, isHardBillingMessage, isUsageLimitError, localWireModelId, palsuAssistantMessage, palsuText, palsuThinking, palsuToolCall, prewarmAnthropicCache, providerRegistry, redactText, redactValue, registerPalsuProvider, resolveToolSchema, sanitizeMessagesForWire, setProviderDiagnostic, sliceHead, sliceTail, stream, toAnthropicMessages, toOpenAIMessages, toWellFormedText };
package/dist/index.d.ts CHANGED
@@ -314,7 +314,7 @@ declare class StreamResult implements AsyncIterable<StreamEvent> {
314
314
  * Local model ids are namespaced by endpoint (`local/<endpointId>/<rawId>`) so
315
315
  * the same model name served by two machines stays distinct in the registry.
316
316
  * The server only knows the raw id, so strip the routing prefix here — at the
317
- * one place that talks to the wire. Counterpart to gg-core's
317
+ * one place that talks to the wire. Counterpart to @prestyj/core's
318
318
  * `formatLocalModelId`/`parseLocalModelId`.
319
319
  */
320
320
  declare function localWireModelId(id: string): string;
@@ -383,7 +383,7 @@ declare class ProviderRegistryImpl {
383
383
  declare const providerRegistry: ProviderRegistryImpl;
384
384
 
385
385
  /**
386
- * Error model for gg-ai and downstream consumers.
386
+ * Error model for @prestyj/ai and downstream consumers.
387
387
  *
388
388
  * Every error users see should answer one question: "is this me or them?"
389
389
  * That answer drives whether they retry, switch model, log in, or report a
@@ -450,7 +450,7 @@ declare class ProviderError extends EZCoderAIError {
450
450
  * transient per-minute throttle)? These don't clear with a quick retry — the
451
451
  * user has to wait for the window to reset — so callers must surface them as a
452
452
  * hard stop, not silently retry for minutes. Detected from the canonical
453
- * "usage limit reached" message gg-ai stamps onto the ProviderError.
453
+ * "usage limit reached" message @prestyj/ai stamps onto the ProviderError.
454
454
  */
455
455
  declare function isUsageLimitError(err: unknown): boolean;
456
456
  /**
@@ -521,7 +521,7 @@ declare function sliceTail(text: string, chars: number): string;
521
521
  declare function sanitizeMessagesForWire(messages: Message[]): Message[];
522
522
 
523
523
  /**
524
- * Provider-level diagnostic hook. Mirrors the pattern used by gg-agent's
524
+ * Provider-level diagnostic hook. Mirrors the pattern used by @prestyj/agent's
525
525
  * setStreamDiagnostic — the host app wires a callback (typically writing to
526
526
  * a debug log) and providers call `providerDiag(...)` to record interesting
527
527
  * lifecycle events (e.g. raw SSE event types and timings).
@@ -530,6 +530,47 @@ type ProviderDiagnosticFn = (phase: string, data?: Record<string, unknown>) => v
530
530
  /** Register a diagnostic callback for provider-level tracing. */
531
531
  declare function setProviderDiagnostic(fn: ProviderDiagnosticFn | null): void;
532
532
 
533
+ /**
534
+ * Converts a Zod schema to a JSON Schema object suitable for provider tool
535
+ * parameter definitions.
536
+ *
537
+ * Anthropic's `input_schema` validator is strict in two ways:
538
+ *
539
+ * 1. The root must be `type: "object"`. Returns 400 with
540
+ * `tools.N.custom.input_schema.type: Field required` otherwise.
541
+ *
542
+ * 2. The root must NOT contain `oneOf`, `anyOf`, or `allOf`. Returns 400 with
543
+ * `input_schema does not support oneOf, allOf, or anyOf at the top level`.
544
+ *
545
+ * Both rules trip whenever a tool's parameters are defined via
546
+ * `z.discriminatedUnion(...)` or `z.union(...)` — Zod 4's
547
+ * `z.toJSONSchema` emits `{oneOf: [...]}` at the root with no `type`.
548
+ *
549
+ * The fix is to collapse the union into a single flat object schema:
550
+ *
551
+ * - properties = union of all branch properties (later branches win on
552
+ * conflict; that's fine because the model only uses these for hints —
553
+ * Zod's actual `tool.parameters.parse(args)` is the real validator)
554
+ * - required = intersection of branch `required` arrays (a field is only
555
+ * required if EVERY branch requires it)
556
+ * - if the union has a discriminator field (every branch has the same
557
+ * property as a `const`), we replace the discriminator's per-branch
558
+ * `const` with an `enum` listing every literal — the model gets a clear
559
+ * hint of the valid action values without needing oneOf
560
+ *
561
+ * The flattening is lossy for *schema-level* constraints (e.g. "if action=X,
562
+ * then field Y is required") — Zod still enforces those at parse time. For
563
+ * the model's purposes this is identical to a single object with optional
564
+ * fields and a discriminator enum, which is exactly how Anthropic-supported
565
+ * tools are typically authored anyway.
566
+ */
567
+ type JsonSchema = Record<string, unknown>;
568
+ /**
569
+ * Resolve a tool's JSON Schema for provider tool definitions: prefer the
570
+ * tool's pre-built `rawInputSchema`, otherwise convert its Zod `parameters`.
571
+ */
572
+ declare function resolveToolSchema(tool: Tool): JsonSchema;
573
+
533
574
  /**
534
575
  * Cap historical images before provider dispatch, removing the oldest first.
535
576
  * The persisted/live conversation is never mutated; only modified messages and
@@ -642,4 +683,4 @@ interface PalsuProviderConfig {
642
683
  */
643
684
  declare function registerPalsuProvider(config?: PalsuProviderConfig): PalsuProviderHandle;
644
685
 
645
- export { type AssistantMessage, type CacheRetention, type ContentPart, type DoneEvent, EZCoderAIError, type ErrorEvent, type ErrorSource, EventStream, type FormattedError, type ImageContent, type Message, type MessageProvenance, type MessageProvenanceKind, type MessageProvenanceSource, type MessageProvenanceVisibility, type PalsuModelConfig, type PalsuModelHandle, type PalsuProviderConfig, type PalsuProviderHandle, type PalsuProviderState, type PalsuResponse, type PalsuResponseFactory, type Provider, type ProviderDiagnosticFn, type ProviderEntry, ProviderError, type ProviderStreamFn, REDACTED as REDACTION_MARKER, type RawContent, type RedactionOptions, type ServerToolCall, type ServerToolCallEvent, type ServerToolDefinition, type ServerToolResult, type ServerToolResultEvent, type StopReason, type StreamEvent, type StreamOptions, type StreamResponse, StreamResult, type SystemMessage, type TextContent, type TextDeltaEvent, type ThinkingContent, type ThinkingDeltaEvent, type ThinkingLevel, type Tool, type ToolCall, type ToolCallDeltaEvent, type ToolCallDoneEvent, type ToolChoice, type ToolResult, type ToolResultContent, type ToolResultMessage, type Usage, type UserMessage, type VideoContent, clampProviderContextImages, classifyProviderError, environmentSecrets, formatError, formatErrorForDisplay, hasLoneSurrogate, isHardBillingMessage, isUsageLimitError, localWireModelId, palsuAssistantMessage, palsuText, palsuThinking, palsuToolCall, prewarmAnthropicCache, providerRegistry, redactText, redactValue, registerPalsuProvider, sanitizeMessagesForWire, setProviderDiagnostic, sliceHead, sliceTail, stream, toAnthropicMessages, toOpenAIMessages, toWellFormedText };
686
+ export { type AssistantMessage, type CacheRetention, type ContentPart, type DoneEvent, EZCoderAIError, type ErrorEvent, type ErrorSource, EventStream, type FormattedError, type ImageContent, type Message, type MessageProvenance, type MessageProvenanceKind, type MessageProvenanceSource, type MessageProvenanceVisibility, type PalsuModelConfig, type PalsuModelHandle, type PalsuProviderConfig, type PalsuProviderHandle, type PalsuProviderState, type PalsuResponse, type PalsuResponseFactory, type Provider, type ProviderDiagnosticFn, type ProviderEntry, ProviderError, type ProviderStreamFn, REDACTED as REDACTION_MARKER, type RawContent, type RedactionOptions, type ServerToolCall, type ServerToolCallEvent, type ServerToolDefinition, type ServerToolResult, type ServerToolResultEvent, type StopReason, type StreamEvent, type StreamOptions, type StreamResponse, StreamResult, type SystemMessage, type TextContent, type TextDeltaEvent, type ThinkingContent, type ThinkingDeltaEvent, type ThinkingLevel, type Tool, type ToolCall, type ToolCallDeltaEvent, type ToolCallDoneEvent, type ToolChoice, type ToolResult, type ToolResultContent, type ToolResultMessage, type Usage, type UserMessage, type VideoContent, clampProviderContextImages, classifyProviderError, environmentSecrets, formatError, formatErrorForDisplay, hasLoneSurrogate, isHardBillingMessage, isUsageLimitError, localWireModelId, palsuAssistantMessage, palsuText, palsuThinking, palsuToolCall, prewarmAnthropicCache, providerRegistry, redactText, redactValue, registerPalsuProvider, resolveToolSchema, sanitizeMessagesForWire, setProviderDiagnostic, sliceHead, sliceTail, stream, toAnthropicMessages, toOpenAIMessages, toWellFormedText };
package/dist/index.js CHANGED
@@ -1105,6 +1105,9 @@ function toLocalReasoningEffort(level) {
1105
1105
  if (level === "max" || level === "ultra" || level === "xhigh") return "max";
1106
1106
  return level;
1107
1107
  }
1108
+ function toGlmReasoningEffort(level) {
1109
+ return level === "ultra" ? "max" : level;
1110
+ }
1108
1111
  function toOpenAIReasoningEffort(level, model) {
1109
1112
  const effort = level === "max" || level === "ultra" ? "xhigh" : level;
1110
1113
  if (model.startsWith("fugu") && (effort === "low" || effort === "medium")) {
@@ -1160,7 +1163,7 @@ function parseToolArguments(argsJson) {
1160
1163
  var NON_STREAMING_TIMEOUT_MS = 60 * 60 * 1e3;
1161
1164
  var anthropicClientCache = /* @__PURE__ */ new Map();
1162
1165
  function fineGrainedToolStreamingEnabled() {
1163
- const raw = process.env.GG_FINE_GRAINED_TOOL_STREAMING ?? process.env.CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING;
1166
+ const raw = process.env.EZ_FINE_GRAINED_TOOL_STREAMING ?? process.env.CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING;
1164
1167
  if (!raw) return false;
1165
1168
  const v = raw.trim().toLowerCase();
1166
1169
  return v === "1" || v === "true" || v === "yes" || v === "on";
@@ -1974,6 +1977,11 @@ async function* runStream2(options) {
1974
1977
  if (usesThinkingParam) {
1975
1978
  if (options.thinking) {
1976
1979
  params.thinking = { type: "enabled" };
1980
+ if (options.provider === "glm") {
1981
+ params.reasoning_effort = toGlmReasoningEffort(
1982
+ options.thinking
1983
+ );
1984
+ }
1977
1985
  } else {
1978
1986
  params.thinking = { type: "disabled" };
1979
1987
  }
@@ -2025,7 +2033,15 @@ async function* runStream2(options) {
2025
2033
  if (chunk.usage) {
2026
2034
  ({ inputTokens, outputTokens, cacheRead, cacheWrite } = extractOpenAIUsage(chunk.usage));
2027
2035
  }
2028
- if (!choice) continue;
2036
+ if (!choice) {
2037
+ const gatewayError = classifyChoicelessFrame(chunk);
2038
+ if (gatewayError) {
2039
+ throw new ProviderError(providerName, gatewayError.message, {
2040
+ statusCode: gatewayError.statusCode
2041
+ });
2042
+ }
2043
+ continue;
2044
+ }
2029
2045
  if (choice.finish_reason) {
2030
2046
  finishReason = choice.finish_reason;
2031
2047
  }
@@ -2209,6 +2225,31 @@ function completionToResponse(completion, endpointKey) {
2209
2225
  }
2210
2226
  };
2211
2227
  }
2228
+ function classifyChoicelessFrame(frame) {
2229
+ if (!frame || typeof frame !== "object" || Array.isArray(frame)) return null;
2230
+ const rec = frame;
2231
+ if (Array.isArray(rec.choices)) return null;
2232
+ const statusOf = (value) => {
2233
+ const n = typeof value === "string" ? Number(value) : value;
2234
+ return typeof n === "number" && Number.isFinite(n) && n >= 400 && n <= 599 ? n : void 0;
2235
+ };
2236
+ const statusCode = statusOf(rec.status) ?? statusOf(rec.statusCode) ?? statusOf(rec.code);
2237
+ const typeIsError = typeof rec.type === "string" && rec.type.toLowerCase() === "error";
2238
+ let detailText;
2239
+ const detail = rec.detail;
2240
+ if (typeof detail === "string" && detail.trim()) {
2241
+ detailText = detail.trim();
2242
+ } else if (Array.isArray(detail)) {
2243
+ const parts = detail.map(
2244
+ (d) => d && typeof d === "object" && typeof d.msg === "string" ? d.msg : typeof d === "string" ? d : ""
2245
+ ).filter(Boolean);
2246
+ if (parts.length) detailText = parts.join("; ");
2247
+ }
2248
+ if (statusCode === void 0 && !typeIsError && !detailText) return null;
2249
+ 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.");
2250
+ const message = rawMessage.slice(0, 500);
2251
+ return { message, statusCode };
2252
+ }
2212
2253
  function classifyOpenAICompatLimit(args) {
2213
2254
  const { status, code, type, message } = args;
2214
2255
  const codeType = `${code ?? ""} ${type ?? ""}`.toLowerCase();
@@ -2220,6 +2261,7 @@ function classifyOpenAICompatLimit(args) {
2220
2261
  return null;
2221
2262
  }
2222
2263
  function toError2(err, provider = "openai") {
2264
+ if (err instanceof ProviderError) return err;
2223
2265
  if (err instanceof OpenAI.APIError) {
2224
2266
  const body = err.error;
2225
2267
  const bodyMessage = typeof body?.message === "string" && body.message.trim() ? body.message.trim() : void 0;
@@ -3580,6 +3622,8 @@ function sanitizeMessagesForWire(messages) {
3580
3622
  // src/stream.ts
3581
3623
  var GLM_CODING_BASE_URL = "https://api.z.ai/api/coding/paas/v4";
3582
3624
  var KIMI_CODE_USER_AGENT = `kimi-code-cli/${process.env.KIMI_CODE_VERSION ?? "1.0.11"}`;
3625
+ var GROK_CLI_PROXY_HOST = "cli-chat-proxy.grok.com";
3626
+ var GROK_CLI_VERSION = process.env.GROK_CLI_VERSION ?? "0.2.101";
3583
3627
  providerRegistry.register("anthropic", {
3584
3628
  stream: (options) => streamAnthropic(options)
3585
3629
  });
@@ -3646,13 +3690,25 @@ providerRegistry.register("xai", {
3646
3690
  // xAI's public API (console.x.ai key) is OpenAI-compatible — ride the Chat
3647
3691
  // Completions transport like Moonshot/DeepSeek. Grok reasoning models take
3648
3692
  // top-level `reasoning_effort` (low/medium/high), which the shared thinking
3649
- // path already sends. xAI's OAuth path exists but only via the Grok CLI's
3650
- // private Responses proxy (cli-chat-proxy.grok.com) with reverse-engineered
3651
- // attribution headers and account-tier gating — intentionally not wired.
3652
- stream: (options) => streamOpenAI({
3653
- ...options,
3654
- baseUrl: options.baseUrl ?? "https://api.x.ai/v1"
3655
- })
3693
+ // path already sends.
3694
+ //
3695
+ // Subscription OAuth (SuperGrok / X Premium) routes to the Grok CLI chat proxy
3696
+ // instead, which speaks the same Chat Completions wire but gates on Grok-CLI
3697
+ // client identity. Inject those headers centrally here — exactly as the Kimi
3698
+ // endpoint above — so EVERY stream (agent loop, compaction, title-gen,
3699
+ // sub-agents) is accepted rather than depending on each call site to thread
3700
+ // headers. Caller-provided headers still win on collision.
3701
+ stream: (options) => {
3702
+ const baseUrl = options.baseUrl ?? "https://api.x.ai/v1";
3703
+ const defaultHeaders = baseUrl.includes(GROK_CLI_PROXY_HOST) ? {
3704
+ "X-XAI-Token-Auth": "xai-grok-cli",
3705
+ "x-grok-client-version": GROK_CLI_VERSION,
3706
+ "x-grok-client-identifier": "ezcoder",
3707
+ "x-grok-model-override": options.model,
3708
+ ...options.defaultHeaders
3709
+ } : options.defaultHeaders;
3710
+ return streamOpenAI({ ...options, baseUrl, defaultHeaders });
3711
+ }
3656
3712
  });
3657
3713
  providerRegistry.register("minimax", {
3658
3714
  stream: (options) => streamAnthropic({
@@ -4114,6 +4170,7 @@ export {
4114
4170
  redactText,
4115
4171
  redactValue,
4116
4172
  registerPalsuProvider,
4173
+ resolveToolSchema,
4117
4174
  sanitizeMessagesForWire,
4118
4175
  setProviderDiagnostic,
4119
4176
  sliceHead,