@prestyj/ai 5.2.0 → 5.3.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.
package/dist/index.js CHANGED
@@ -1036,6 +1036,12 @@ function parseToolArguments(argsJson) {
1036
1036
  // src/providers/anthropic.ts
1037
1037
  var NON_STREAMING_TIMEOUT_MS = 60 * 60 * 1e3;
1038
1038
  var anthropicClientCache = /* @__PURE__ */ new Map();
1039
+ function fineGrainedToolStreamingEnabled() {
1040
+ const raw = process.env.GG_FINE_GRAINED_TOOL_STREAMING ?? process.env.CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING;
1041
+ if (!raw) return false;
1042
+ const v = raw.trim().toLowerCase();
1043
+ return v === "1" || v === "true" || v === "yes" || v === "on";
1044
+ }
1039
1045
  function createClient(options) {
1040
1046
  const isOAuth = options.apiKey?.startsWith("sk-ant-oat");
1041
1047
  const userAgent = isOAuth ? options.userAgent ?? "claude-cli/2.1.75 (external, cli)" : "";
@@ -1093,7 +1099,9 @@ async function prewarmAnthropicCache(options) {
1093
1099
  ] : system;
1094
1100
  const tools = options.tools?.length ? toAnthropicTools(options.tools, {
1095
1101
  cacheControl,
1096
- enableFineGrainedToolStreaming: true
1102
+ // Keep the serialized tool bytes identical to runStream so the
1103
+ // prewarmed prompt cache actually hits — both are gated by the flag.
1104
+ enableFineGrainedToolStreaming: fineGrainedToolStreamingEnabled()
1097
1105
  }) : void 0;
1098
1106
  await client.messages.create(
1099
1107
  {
@@ -1173,7 +1181,7 @@ async function* runStream(options) {
1173
1181
  options.tools.filter((t) => !reservedServerNames.has(t.name)),
1174
1182
  {
1175
1183
  ...supportsFirstPartyToolExtras && cacheControl ? { cacheControl } : {},
1176
- ...supportsFirstPartyToolExtras ? { enableFineGrainedToolStreaming: true } : {}
1184
+ ...supportsFirstPartyToolExtras && fineGrainedToolStreamingEnabled() ? { enableFineGrainedToolStreaming: true } : {}
1177
1185
  }
1178
1186
  ) : [];
1179
1187
  return {
@@ -1199,7 +1207,10 @@ async function* runStream(options) {
1199
1207
  ...isOAuth ? ["claude-code-20250219", "oauth-2025-04-20"] : [],
1200
1208
  ...options.compaction ? ["compact-2026-01-12"] : [],
1201
1209
  ...options.clearToolUses ? ["context-management-2025-06-27"] : [],
1202
- "fine-grained-tool-streaming-2025-05-14",
1210
+ // Eager tool-input streaming beta — opt-in only (see
1211
+ // fineGrainedToolStreamingEnabled). Off by default: the un-buffered stream
1212
+ // truncates large tool payloads into malformed JSON → phantom empty calls.
1213
+ ...fineGrainedToolStreamingEnabled() ? ["fine-grained-tool-streaming-2025-05-14"] : [],
1203
1214
  ...!hasAdaptiveThinking ? ["interleaved-thinking-2025-05-14"] : [],
1204
1215
  // The 1-h cache TTL (cacheRetention "long") is gated behind this beta. Without
1205
1216
  // it Anthropic silently ignores ttl:"1h" and falls back to the 5-min default,
@@ -1332,7 +1343,14 @@ async function* runStream(options) {
1332
1343
  try {
1333
1344
  const parsed = JSON.parse(accum.argsJson);
1334
1345
  args = isJsonObject(parsed) ? parsed : {};
1335
- } catch {
1346
+ } catch (parseErr) {
1347
+ const rawPartial = accum.argsJson;
1348
+ const snippet = rawPartial.length > 200 ? `${rawPartial.slice(0, 200)}\u2026` : rawPartial;
1349
+ throw new ProviderError(
1350
+ "anthropic",
1351
+ `Tool "${accum.toolName}" input JSON was truncated in the stream (${rawPartial.length} bytes): ${snippet}; ${parseErr.message}`,
1352
+ { cause: parseErr }
1353
+ );
1336
1354
  }
1337
1355
  }
1338
1356
  const tc = {
@@ -1553,6 +1571,7 @@ function readUnifiedRateLimit(headers) {
1553
1571
  return { rejected: status === "rejected", ...resetsAt ? { resetsAt } : {} };
1554
1572
  }
1555
1573
  function toError(err) {
1574
+ if (err instanceof ProviderError) return err;
1556
1575
  if (err instanceof Anthropic.APIError) {
1557
1576
  const errorBody = err.error;
1558
1577
  const nestedError = errorBody?.error;