@prestyj/ai 4.11.4 → 4.12.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
@@ -43,6 +43,7 @@ __export(index_exports, {
43
43
  palsuText: () => palsuText,
44
44
  palsuThinking: () => palsuThinking,
45
45
  palsuToolCall: () => palsuToolCall,
46
+ prewarmAnthropicCache: () => prewarmAnthropicCache,
46
47
  providerRegistry: () => providerRegistry,
47
48
  registerPalsuProvider: () => registerPalsuProvider,
48
49
  setProviderDiagnostic: () => setProviderDiagnostic,
@@ -418,10 +419,15 @@ var StreamResult = class {
418
419
 
419
420
  // src/utils/zod-to-json-schema.ts
420
421
  var import_zod = require("zod");
422
+ var schemaCache = /* @__PURE__ */ new WeakMap();
421
423
  function zodToJsonSchema(schema) {
424
+ const cached = schemaCache.get(schema);
425
+ if (cached) return cached;
422
426
  const jsonSchema = import_zod.z.toJSONSchema(schema);
423
427
  const { $schema: _schema, ...rest } = jsonSchema;
424
- return normalizeRootForAnthropic(rest);
428
+ const normalized = normalizeRootForAnthropic(rest);
429
+ schemaCache.set(schema, normalized);
430
+ return normalized;
425
431
  }
426
432
  function resolveToolSchema(tool) {
427
433
  return tool.rawInputSchema ?? zodToJsonSchema(tool.parameters);
@@ -1029,26 +1035,86 @@ function parseToolArguments(argsJson) {
1029
1035
  }
1030
1036
 
1031
1037
  // src/providers/anthropic.ts
1038
+ var anthropicClientCache = /* @__PURE__ */ new Map();
1032
1039
  function createClient(options) {
1033
1040
  const isOAuth = options.apiKey?.startsWith("sk-ant-oat");
1034
- return new import_sdk.default({
1041
+ const userAgent = isOAuth ? options.userAgent ?? "claude-cli/2.1.75 (external, cli)" : "";
1042
+ const cacheKey = `${options.apiKey ?? ""}|${options.baseUrl ?? ""}|${userAgent}`;
1043
+ if (!options.fetch) {
1044
+ const cached = anthropicClientCache.get(cacheKey);
1045
+ if (cached) return cached;
1046
+ }
1047
+ const client = new import_sdk.default({
1035
1048
  ...isOAuth ? { apiKey: null, authToken: options.apiKey } : { apiKey: options.apiKey },
1036
1049
  ...options.baseUrl ? { baseURL: options.baseUrl } : {},
1037
1050
  ...options.fetch ? { fetch: options.fetch } : {},
1038
- // Disable SDK retries — the agent loop has its own stall/overload retry
1039
- // logic that surfaces errors properly. SDK retries on 429s can cause
1040
- // multi-minute hangs when the provider stops responding mid-retry.
1041
1051
  maxRetries: 0,
1042
1052
  ...isOAuth ? {
1043
1053
  defaultHeaders: {
1044
1054
  // Anthropic's OAuth edge validates the claude-cli version. Callers
1045
1055
  // (ezcoder) resolve the live version at runtime; the literal here
1046
- // is the offline fallback for direct gg-ai consumers.
1047
- "user-agent": options.userAgent ?? "claude-cli/2.1.75 (external, cli)",
1056
+ // is the offline fallback for direct ai consumers.
1057
+ "user-agent": userAgent,
1048
1058
  "x-app": "cli"
1049
1059
  }
1050
1060
  } : {}
1051
1061
  });
1062
+ if (!options.fetch) {
1063
+ if (anthropicClientCache.size >= 8) {
1064
+ const oldest = anthropicClientCache.keys().next().value;
1065
+ if (oldest) anthropicClientCache.delete(oldest);
1066
+ }
1067
+ anthropicClientCache.set(cacheKey, client);
1068
+ }
1069
+ return client;
1070
+ }
1071
+ async function prewarmAnthropicCache(options) {
1072
+ try {
1073
+ const client = createClient({
1074
+ apiKey: options.apiKey,
1075
+ baseUrl: options.baseUrl,
1076
+ userAgent: options.userAgent
1077
+ });
1078
+ const cacheControl = toAnthropicCacheControl(options.cacheRetention ?? "long", options.baseUrl);
1079
+ const { system, messages } = toAnthropicMessages(
1080
+ [
1081
+ { role: "system", content: options.system },
1082
+ { role: "user", content: "." }
1083
+ ],
1084
+ cacheControl
1085
+ );
1086
+ const isOAuth = options.apiKey.startsWith("sk-ant-oat");
1087
+ const fullSystem = isOAuth ? [
1088
+ {
1089
+ type: "text",
1090
+ text: "You are Claude Code, Anthropic's official CLI for Claude."
1091
+ },
1092
+ ...system ?? []
1093
+ ] : system;
1094
+ const tools = options.tools?.length ? toAnthropicTools(options.tools, {
1095
+ cacheControl,
1096
+ enableFineGrainedToolStreaming: true
1097
+ }) : void 0;
1098
+ await client.messages.create(
1099
+ {
1100
+ model: options.model,
1101
+ max_tokens: 1,
1102
+ messages,
1103
+ ...fullSystem ? { system: fullSystem } : {},
1104
+ ...tools ? {
1105
+ tools: [
1106
+ ...tools,
1107
+ ...options.serverTools ?? []
1108
+ ]
1109
+ } : {}
1110
+ },
1111
+ {
1112
+ signal: options.signal ?? void 0,
1113
+ ...isOAuth ? { headers: { "anthropic-beta": "claude-code-20250219,oauth-2025-04-20" } } : {}
1114
+ }
1115
+ );
1116
+ } catch {
1117
+ }
1052
1118
  }
1053
1119
  function streamAnthropic(options) {
1054
1120
  return new StreamResult(runStream(options), options.signal);
@@ -1628,13 +1694,27 @@ function extractOpenAIUsage(usage) {
1628
1694
  cacheRead
1629
1695
  };
1630
1696
  }
1697
+ var openaiClientCache = /* @__PURE__ */ new Map();
1631
1698
  function createClient2(options) {
1632
- return new import_openai.default({
1699
+ const cacheKey = `${options.apiKey ?? ""}|${options.baseUrl ?? ""}|${JSON.stringify(options.defaultHeaders ?? {})}`;
1700
+ if (!options.fetch) {
1701
+ const cached = openaiClientCache.get(cacheKey);
1702
+ if (cached) return cached;
1703
+ }
1704
+ const client = new import_openai.default({
1633
1705
  apiKey: options.apiKey,
1634
1706
  ...options.baseUrl ? { baseURL: options.baseUrl } : {},
1635
1707
  ...options.fetch ? { fetch: options.fetch } : {},
1636
1708
  ...options.defaultHeaders ? { defaultHeaders: options.defaultHeaders } : {}
1637
1709
  });
1710
+ if (!options.fetch) {
1711
+ if (openaiClientCache.size >= 8) {
1712
+ const oldest = openaiClientCache.keys().next().value;
1713
+ if (oldest) openaiClientCache.delete(oldest);
1714
+ }
1715
+ openaiClientCache.set(cacheKey, client);
1716
+ }
1717
+ return client;
1638
1718
  }
1639
1719
  function streamOpenAI(options) {
1640
1720
  return new StreamResult(runStream2(options), options.signal);
@@ -2049,9 +2129,6 @@ async function* runStream3(options) {
2049
2129
  body.tools = toCodexTools(options.tools);
2050
2130
  }
2051
2131
  body.prompt_cache_key = normalizePromptCacheKey(options.promptCacheKey ?? "ezcoder");
2052
- if (options.cacheRetention === "long") {
2053
- body.prompt_cache_retention = "24h";
2054
- }
2055
2132
  if (options.temperature != null && !options.thinking) {
2056
2133
  body.temperature = options.temperature;
2057
2134
  }
@@ -3365,6 +3442,7 @@ function registerPalsuProvider(config) {
3365
3442
  palsuText,
3366
3443
  palsuThinking,
3367
3444
  palsuToolCall,
3445
+ prewarmAnthropicCache,
3368
3446
  providerRegistry,
3369
3447
  registerPalsuProvider,
3370
3448
  setProviderDiagnostic,