@kenkaiiii/gg-ai 5.89.0 → 5.90.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.cjs CHANGED
@@ -35,6 +35,7 @@ __export(index_exports, {
35
35
  EventStream: () => EventStream,
36
36
  FAST_MODE_SUFFIX: () => FAST_MODE_SUFFIX,
37
37
  GGAIError: () => GGAIError,
38
+ LOCAL_NO_API_KEY: () => LOCAL_NO_API_KEY,
38
39
  PRECONNECT_INTERVAL_MS: () => PRECONNECT_INTERVAL_MS,
39
40
  ProviderError: () => ProviderError,
40
41
  REDACTION_MARKER: () => REDACTED,
@@ -57,6 +58,7 @@ __export(index_exports, {
57
58
  isHardBillingMessage: () => isHardBillingMessage,
58
59
  isUsageLimitError: () => isUsageLimitError,
59
60
  isValidToolCallName: () => isValidToolCallName,
61
+ localBearerKey: () => localBearerKey,
60
62
  localWireModelId: () => localWireModelId,
61
63
  opensTurn: () => opensTurn,
62
64
  palsuAssistantMessage: () => palsuAssistantMessage,
@@ -1656,10 +1658,22 @@ function toAnthropicMessages(messages, cacheControl, options) {
1656
1658
  (name) => toolReferences.has(name) && !referencedTools.has(name)
1657
1659
  ) : [];
1658
1660
  if (refs.length === 0) {
1661
+ const content = toAnthropicToolResultContent(result.content);
1662
+ if (result.isError && typeof content !== "string" && content.some((part) => part.type !== "text")) {
1663
+ const text = content.filter((part) => part.type === "text" && part.text !== "");
1664
+ trailing.push({ type: "text", text: `Attachments from tool call ${toolUseId}:` });
1665
+ for (const part of content) if (part.type !== "text") trailing.push(part);
1666
+ return {
1667
+ type: "tool_result",
1668
+ tool_use_id: toolUseId,
1669
+ content: text.length > 0 ? text : "Tool call failed; its attachments follow.",
1670
+ is_error: true
1671
+ };
1672
+ }
1659
1673
  return {
1660
1674
  type: "tool_result",
1661
1675
  tool_use_id: toolUseId,
1662
- content: toAnthropicToolResultContent(result.content),
1676
+ content,
1663
1677
  is_error: result.isError
1664
1678
  };
1665
1679
  }
@@ -1678,7 +1692,8 @@ ${part.text}` } : part
1678
1692
  type: "tool_result",
1679
1693
  tool_use_id: toolUseId,
1680
1694
  content: refs.map((name) => ({ type: "tool_reference", tool_name: name })),
1681
- is_error: result.isError
1695
+ // tool_reference isn't text, so is_error would 400; the error text trails.
1696
+ is_error: void 0
1682
1697
  };
1683
1698
  });
1684
1699
  out.push({
@@ -1701,8 +1716,8 @@ ${part.text}` } : part
1701
1716
  markAnthropicCacheBreakpoint(out, tail, cacheControl);
1702
1717
  } else {
1703
1718
  if (anchor !== void 0) markAnthropicCacheBreakpoint(out, anchor, cacheControl);
1704
- const longRun = isLongToolRun(messages, trajectoryStartIdx);
1705
- markAnthropicCacheBreakpoint(out, tail, longRun ? cacheControl : { type: "ephemeral" });
1719
+ const blocking = calledBlockingTool(messages, trajectoryStartIdx);
1720
+ markAnthropicCacheBreakpoint(out, tail, blocking ? cacheControl : { type: "ephemeral" });
1706
1721
  }
1707
1722
  } else {
1708
1723
  markAnthropicCacheBreakpoint(out, tail, cacheControl);
@@ -1738,19 +1753,13 @@ var BLOCKING_TOOL_NAMES = /* @__PURE__ */ new Set([
1738
1753
  "subagent",
1739
1754
  "ask_user"
1740
1755
  ]);
1741
- var LONG_RUN_ROUNDS = 6;
1742
- function isLongToolRun(messages, trajectoryStartIdx) {
1743
- let rounds = 0;
1756
+ function calledBlockingTool(messages, trajectoryStartIdx) {
1744
1757
  for (let i = Math.max(0, trajectoryStartIdx + 1); i < messages.length; i++) {
1745
1758
  const m = messages[i];
1746
1759
  if (m?.role !== "assistant" || typeof m.content === "string") continue;
1747
- let called = false;
1748
1760
  for (const part of m.content) {
1749
- if (part.type !== "tool_call") continue;
1750
- called = true;
1751
- if (BLOCKING_TOOL_NAMES.has(part.name)) return true;
1761
+ if (part.type === "tool_call" && BLOCKING_TOOL_NAMES.has(part.name)) return true;
1752
1762
  }
1753
- if (called && ++rounds >= LONG_RUN_ROUNDS) return true;
1754
1763
  }
1755
1764
  return false;
1756
1765
  }
@@ -2937,6 +2946,12 @@ function getEnvironment() {
2937
2946
  return globalThis.process?.env;
2938
2947
  }
2939
2948
 
2949
+ // src/local-api-key.ts
2950
+ var LOCAL_NO_API_KEY = "local";
2951
+ function localBearerKey(apiKey) {
2952
+ return apiKey && apiKey !== LOCAL_NO_API_KEY ? apiKey : void 0;
2953
+ }
2954
+
2940
2955
  // src/providers/openai.ts
2941
2956
  function toKimiK3Effort(level) {
2942
2957
  switch (level) {
@@ -2981,6 +2996,8 @@ function createClient2(options) {
2981
2996
  const cached = openaiClientCache.get(cacheKey);
2982
2997
  if (cached) return cached;
2983
2998
  }
2999
+ const omitAuth = options.provider === "local" && localBearerKey(options.apiKey) === void 0;
3000
+ const defaultHeaders = omitAuth ? { ...options.defaultHeaders, Authorization: null } : options.defaultHeaders;
2984
3001
  const client = new import_openai.default({
2985
3002
  apiKey: options.apiKey,
2986
3003
  ...options.baseUrl ? { baseURL: options.baseUrl } : {},
@@ -2990,7 +3007,7 @@ function createClient2(options) {
2990
3007
  // events). The SDK default of 2 silent retries stacked under it: one 5xx
2991
3008
  // cost up to 3 hidden requests plus SDK sleeps before the loop even saw it.
2992
3009
  maxRetries: 0,
2993
- ...options.defaultHeaders ? { defaultHeaders: options.defaultHeaders } : {}
3010
+ ...defaultHeaders ? { defaultHeaders } : {}
2994
3011
  });
2995
3012
  if (!options.fetch) {
2996
3013
  if (openaiClientCache.size >= 8) {
@@ -5747,19 +5764,25 @@ providerRegistry.register("local", {
5747
5764
  }),
5748
5765
  // Every supported local server exposes OpenAI-compatible `/v1/embeddings`
5749
5766
  // (the model must be an embedding model). None has an input-type parameter.
5750
- embed: (request) => embedOpenAICompatible(request, {
5751
- provider: "local",
5752
- baseUrl: requireLocalBaseUrl(request.baseUrl),
5753
- wireModel: localWireModelId(request.model)
5754
- }),
5767
+ embed: (request) => embedOpenAICompatible(
5768
+ { ...request, apiKey: localBearerKey(request.apiKey) },
5769
+ {
5770
+ provider: "local",
5771
+ baseUrl: requireLocalBaseUrl(request.baseUrl),
5772
+ wireModel: localWireModelId(request.model)
5773
+ }
5774
+ ),
5755
5775
  embedBatchSize: LOCAL_EMBED_BATCH_SIZE,
5756
5776
  // llama.cpp (`llama-server --rerank`) and vLLM serve `/v1/rerank`; Ollama and
5757
5777
  // LM Studio don't, and answer with a 404 ProviderError.
5758
- rerank: (request) => rerankCohereCompatible(request, {
5759
- provider: "local",
5760
- baseUrl: requireLocalBaseUrl(request.baseUrl),
5761
- wireModel: localWireModelId(request.model)
5762
- })
5778
+ rerank: (request) => rerankCohereCompatible(
5779
+ { ...request, apiKey: localBearerKey(request.apiKey) },
5780
+ {
5781
+ provider: "local",
5782
+ baseUrl: requireLocalBaseUrl(request.baseUrl),
5783
+ wireModel: localWireModelId(request.model)
5784
+ }
5785
+ )
5763
5786
  });
5764
5787
  function requireLocalBaseUrl(baseUrl) {
5765
5788
  if (!baseUrl) {
@@ -6133,6 +6156,13 @@ function formatChatError(error) {
6133
6156
  "Check your connection before trying again."
6134
6157
  );
6135
6158
  }
6159
+ if (base.provider === "local" && (base.source === "auth" || base.statusCode === 401)) {
6160
+ return present(
6161
+ "auth",
6162
+ "The local server rejected its key",
6163
+ "Check the endpoint's key under Local models in AI Providers settings."
6164
+ );
6165
+ }
6136
6166
  if (base.source === "auth" || base.statusCode === 401) {
6137
6167
  return present(
6138
6168
  "auth",
@@ -6506,6 +6536,7 @@ function palsuRerankScore(query, document) {
6506
6536
  EventStream,
6507
6537
  FAST_MODE_SUFFIX,
6508
6538
  GGAIError,
6539
+ LOCAL_NO_API_KEY,
6509
6540
  PRECONNECT_INTERVAL_MS,
6510
6541
  ProviderError,
6511
6542
  REDACTION_MARKER,
@@ -6528,6 +6559,7 @@ function palsuRerankScore(query, document) {
6528
6559
  isHardBillingMessage,
6529
6560
  isUsageLimitError,
6530
6561
  isValidToolCallName,
6562
+ localBearerKey,
6531
6563
  localWireModelId,
6532
6564
  opensTurn,
6533
6565
  palsuAssistantMessage,