zelari-code 2.21.0 → 2.22.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.
@@ -44725,7 +44725,10 @@ var init_semantic2 = __esm({
44725
44725
  // src/cli/provider/openai-compatible.ts
44726
44726
  var openai_compatible_exports = {};
44727
44727
  __export(openai_compatible_exports, {
44728
+ PROVIDER_CONNECT_TIMEOUT_MS: () => PROVIDER_CONNECT_TIMEOUT_MS,
44728
44729
  PROVIDER_ENDPOINTS: () => PROVIDER_ENDPOINTS,
44730
+ PROVIDER_STREAM_IDLE_MS: () => PROVIDER_STREAM_IDLE_MS,
44731
+ PROVIDER_STREAM_MAX_MS: () => PROVIDER_STREAM_MAX_MS,
44729
44732
  dataUriFromImage: () => dataUriFromImage,
44730
44733
  modelSupportsVision: () => modelSupportsVision,
44731
44734
  openaiCompatibleProvider: () => openaiCompatibleProvider,
@@ -46760,14 +46763,27 @@ function anthropicMessagesProvider(config2) {
46760
46763
  const base2 = config2.baseUrl.replace(/\/$/, "").replace(/\/v1$/, "");
46761
46764
  const url2 = `${base2}/v1/messages`;
46762
46765
  let response;
46766
+ const connectController = new AbortController();
46767
+ const connectTimer = setTimeout(
46768
+ () => connectController.abort(
46769
+ new Error(
46770
+ `Provider connect timeout after ${Math.round(PROVIDER_CONNECT_TIMEOUT_MS / 1e3)}s (no response headers). Override ZELARI_PROVIDER_CONNECT_TIMEOUT_MS.`
46771
+ )
46772
+ ),
46773
+ PROVIDER_CONNECT_TIMEOUT_MS
46774
+ );
46775
+ const signals = [connectController.signal];
46776
+ if (params.signal) signals.push(params.signal);
46763
46777
  try {
46764
46778
  response = await fetch(url2, {
46765
46779
  method: "POST",
46766
46780
  headers: authHeaders(config2.apiKey, ttlPref === "1h"),
46767
46781
  body: JSON.stringify(body),
46768
- signal: params.signal
46782
+ signal: signals.length === 1 ? signals[0] : AbortSignal.any(signals)
46769
46783
  });
46784
+ clearTimeout(connectTimer);
46770
46785
  } catch (err) {
46786
+ clearTimeout(connectTimer);
46771
46787
  yield {
46772
46788
  kind: "error",
46773
46789
  message: `Network error: ${err instanceof Error ? err.message : String(err)}`
@@ -46802,9 +46818,17 @@ function anthropicMessagesProvider(config2) {
46802
46818
  };
46803
46819
  currentTool = null;
46804
46820
  };
46821
+ const streamStartedAt = Date.now();
46822
+ let lastUsefulAt = streamStartedAt;
46823
+ const streamDeadline = streamStartedAt + PROVIDER_STREAM_MAX_MS;
46805
46824
  try {
46806
46825
  while (true) {
46807
- const { value, done } = await reader.read();
46826
+ const { value, done } = await readChunkWithTimeout(reader, {
46827
+ idleMs: PROVIDER_STREAM_IDLE_MS,
46828
+ deadlineMs: streamDeadline,
46829
+ signal: params.signal,
46830
+ lastUsefulAt: () => lastUsefulAt
46831
+ });
46808
46832
  if (done) break;
46809
46833
  buffer += decoder.decode(value, { stream: true });
46810
46834
  const lines = buffer.split("\n");
@@ -46821,6 +46845,7 @@ function anthropicMessagesProvider(config2) {
46821
46845
  continue;
46822
46846
  }
46823
46847
  const type = ev.type;
46848
+ if (type !== "ping") lastUsefulAt = Date.now();
46824
46849
  if (type === "content_block_delta") {
46825
46850
  const delta = ev.delta;
46826
46851
  if (delta?.type === "text_delta" && typeof delta.text === "string") {
@@ -46894,6 +46919,7 @@ var ANTHROPIC_VERSION, ANTHROPIC_BETA, ANTHROPIC_BETA_EXTENDED_CACHE_TTL;
46894
46919
  var init_anthropic = __esm({
46895
46920
  "src/cli/provider/anthropic.ts"() {
46896
46921
  "use strict";
46922
+ init_openai_compatible();
46897
46923
  init_chatStats();
46898
46924
  init_thinking();
46899
46925
  ANTHROPIC_VERSION = "2023-06-01";
@@ -46972,14 +46998,27 @@ function chatgptResponsesProvider(config2) {
46972
46998
  const base2 = config2.baseUrl.replace(/\/$/, "");
46973
46999
  const url2 = `${base2}/responses`;
46974
47000
  let response;
47001
+ const connectController = new AbortController();
47002
+ const connectTimer = setTimeout(
47003
+ () => connectController.abort(
47004
+ new Error(
47005
+ `Provider connect timeout after ${Math.round(PROVIDER_CONNECT_TIMEOUT_MS / 1e3)}s (no response headers). Override ZELARI_PROVIDER_CONNECT_TIMEOUT_MS.`
47006
+ )
47007
+ ),
47008
+ PROVIDER_CONNECT_TIMEOUT_MS
47009
+ );
47010
+ const signals = [connectController.signal];
47011
+ if (params.signal) signals.push(params.signal);
46975
47012
  try {
46976
47013
  response = await fetch(url2, {
46977
47014
  method: "POST",
46978
47015
  headers: headers(config2),
46979
47016
  body: JSON.stringify(body),
46980
- signal: params.signal
47017
+ signal: signals.length === 1 ? signals[0] : AbortSignal.any(signals)
46981
47018
  });
47019
+ clearTimeout(connectTimer);
46982
47020
  } catch (err) {
47021
+ clearTimeout(connectTimer);
46983
47022
  yield {
46984
47023
  kind: "error",
46985
47024
  message: `Network error: ${err instanceof Error ? err.message : String(err)}`
@@ -47009,9 +47048,17 @@ function chatgptResponsesProvider(config2) {
47009
47048
  emittedTool = true;
47010
47049
  yield { kind: "tool_call", toolCallId: t.id, toolName: t.name, args };
47011
47050
  };
47051
+ const streamStartedAt = Date.now();
47052
+ let lastUsefulAt = streamStartedAt;
47053
+ const streamDeadline = streamStartedAt + PROVIDER_STREAM_MAX_MS;
47012
47054
  try {
47013
47055
  while (true) {
47014
- const { value, done } = await reader.read();
47056
+ const { value, done } = await readChunkWithTimeout(reader, {
47057
+ idleMs: PROVIDER_STREAM_IDLE_MS,
47058
+ deadlineMs: streamDeadline,
47059
+ signal: params.signal,
47060
+ lastUsefulAt: () => lastUsefulAt
47061
+ });
47015
47062
  if (done) break;
47016
47063
  buffer += decoder.decode(value, { stream: true });
47017
47064
  const lines = buffer.split("\n");
@@ -47028,6 +47075,7 @@ function chatgptResponsesProvider(config2) {
47028
47075
  continue;
47029
47076
  }
47030
47077
  const type = typeof ev.type === "string" ? ev.type : "";
47078
+ if (type) lastUsefulAt = Date.now();
47031
47079
  if (type === "response.output_text.delta" && typeof ev.delta === "string") {
47032
47080
  yield { kind: "text", delta: ev.delta };
47033
47081
  } else if (type === "response.reasoning_text.delta" && typeof ev.delta === "string") {
@@ -47083,6 +47131,7 @@ function chatgptResponsesProvider(config2) {
47083
47131
  var init_chatgpt = __esm({
47084
47132
  "src/cli/provider/chatgpt.ts"() {
47085
47133
  "use strict";
47134
+ init_openai_compatible();
47086
47135
  init_thinking();
47087
47136
  }
47088
47137
  });
@@ -62338,7 +62387,7 @@ var MIN_NODE_MAJOR, STANDARD_BASH_PATHS2, POWERSHELL_EXES2, STANDARD_POWERSHELL_
62338
62387
  var init_prereqChecks = __esm({
62339
62388
  "src/cli/utils/prereqChecks.ts"() {
62340
62389
  "use strict";
62341
- MIN_NODE_MAJOR = 20;
62390
+ MIN_NODE_MAJOR = 24;
62342
62391
  STANDARD_BASH_PATHS2 = [
62343
62392
  "C:\\Program Files\\Git\\bin\\bash.exe",
62344
62393
  "C:\\Program Files\\Git\\usr\\bin\\bash.exe",
@@ -70174,12 +70223,15 @@ function checkNode(pkg) {
70174
70223
  return WARN(`could not parse node version: ${raw}`);
70175
70224
  }
70176
70225
  const major = Number(m[1]);
70177
- if (major < 20) {
70226
+ const enginesNode = pkg?.engines?.node;
70227
+ const requiredMajor = Number(enginesNode?.match(/\d+/)?.[0] ?? 20);
70228
+ if (major < requiredMajor) {
70178
70229
  return FAIL(
70179
- `node ${raw} is older than the required engines.node (>= 20.0.0)`
70230
+ `node ${raw} is older than the required engines.node (${enginesNode ?? ">= 20.0.0"})
70231
+ fix: install Node.js ${requiredMajor}+ (LTS) and reopen the terminal`
70180
70232
  );
70181
70233
  }
70182
- return OK(`node ${raw}`);
70234
+ return OK(`node ${raw} (engines.node ${enginesNode ?? ">= 20.0.0"})`);
70183
70235
  }
70184
70236
  function checkBundle() {
70185
70237
  const bundle = path88.join(packageRoot, "dist", "cli", "main.bundled.js");