@tractorscorch/clank 1.4.7 → 1.4.8

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/CHANGELOG.md CHANGED
@@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/).
6
6
 
7
7
  ---
8
8
 
9
+ ## [1.4.8] — 2026-03-22
10
+
11
+ ### Fixed
12
+ - **Model hangs permanently after tool calls** — provider timeout was bypassed when the engine passed its own AbortSignal (always); now uses `AbortSignal.any()` to combine the caller's signal with a hard 120s timeout so hung models are detected and reported instead of blocking forever
13
+ - **No retry on timeout** — engine no longer retries when a model times out (was doubling the wait to 240s with no chance of success); timeouts propagate immediately as errors
14
+
15
+ ---
16
+
9
17
  ## [1.4.7] — 2026-03-22
10
18
 
11
19
  ### Fixed
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
- <a href="https://github.com/ItsTrag1c/Clank/releases/latest"><img src="https://img.shields.io/badge/version-1.4.7-blue.svg" alt="Version" /></a>
12
+ <a href="https://github.com/ItsTrag1c/Clank/releases/latest"><img src="https://img.shields.io/badge/version-1.4.8-blue.svg" alt="Version" /></a>
13
13
  <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License" /></a>
14
14
  <a href="https://www.npmjs.com/package/@tractorscorch/clank"><img src="https://img.shields.io/npm/v/@tractorscorch/clank.svg" alt="npm" /></a>
15
15
  <a href="https://github.com/ItsTrag1c/Clank/stargazers"><img src="https://img.shields.io/github/stars/ItsTrag1c/Clank.svg" alt="Stars" /></a>
@@ -75,7 +75,7 @@ That's it. Setup auto-detects your local models, configures the gateway, and get
75
75
  | Platform | Download |
76
76
  |----------|----------|
77
77
  | **npm** (all platforms) | `npm install -g @tractorscorch/clank` |
78
- | **macOS** (Apple Silicon) | [Clank_1.4.7_macos](https://github.com/ItsTrag1c/Clank/releases/latest/download/Clank_1.4.7_macos) |
78
+ | **macOS** (Apple Silicon) | [Clank_1.4.8_macos](https://github.com/ItsTrag1c/Clank/releases/latest/download/Clank_1.4.8_macos) |
79
79
 
80
80
  ## Features
81
81
 
package/dist/index.js CHANGED
@@ -561,7 +561,8 @@ var init_ollama = __esm({
561
561
  if (this.maxResponseTokens) {
562
562
  body.max_tokens = this.maxResponseTokens;
563
563
  }
564
- const effectiveSignal = signal || AbortSignal.timeout(12e4);
564
+ const timeoutSignal = AbortSignal.timeout(12e4);
565
+ const effectiveSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
565
566
  const res = await fetch(`${this.baseUrl}/v1/chat/completions`, {
566
567
  method: "POST",
567
568
  headers: { "Content-Type": "application/json" },
@@ -947,7 +948,8 @@ var init_agent = __esm({
947
948
  streamSuccess = true;
948
949
  break;
949
950
  } catch (streamErr) {
950
- if (attempt === 0 && !signal.aborted) {
951
+ const isTimeout = streamErr instanceof Error && (streamErr.name === "TimeoutError" || streamErr.name === "AbortError" || streamErr.message.includes("timed out"));
952
+ if (attempt === 0 && !signal.aborted && !isTimeout) {
951
953
  this.emit("error", {
952
954
  message: `Model connection failed, retrying... (${streamErr instanceof Error ? streamErr.message : "unknown"})`,
953
955
  recoverable: true
@@ -2757,7 +2759,8 @@ var init_anthropic = __esm({
2757
2759
  if (tools.length > 0) {
2758
2760
  body.tools = this.formatTools(tools);
2759
2761
  }
2760
- const effectiveSignal = signal || AbortSignal.timeout(9e4);
2762
+ const timeoutSignal = AbortSignal.timeout(9e4);
2763
+ const effectiveSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
2761
2764
  const res = await fetch(`${this.baseUrl}/v1/messages`, {
2762
2765
  method: "POST",
2763
2766
  headers: {
@@ -2984,7 +2987,8 @@ var init_openai = __esm({
2984
2987
  if (this.apiKey) {
2985
2988
  headers["Authorization"] = `Bearer ${this.apiKey}`;
2986
2989
  }
2987
- const effectiveSignal = signal || AbortSignal.timeout(9e4);
2990
+ const timeoutSignal = AbortSignal.timeout(9e4);
2991
+ const effectiveSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
2988
2992
  const res = await fetch(`${this.baseUrl}/v1/chat/completions`, {
2989
2993
  method: "POST",
2990
2994
  headers,
@@ -3211,7 +3215,8 @@ var init_google = __esm({
3211
3215
  body.tools = this.formatTools(tools);
3212
3216
  }
3213
3217
  const url = `https://generativelanguage.googleapis.com/v1beta/models/${this.model}:streamGenerateContent?key=${this.apiKey}&alt=sse`;
3214
- const effectiveSignal = signal || AbortSignal.timeout(9e4);
3218
+ const timeoutSignal = AbortSignal.timeout(9e4);
3219
+ const effectiveSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
3215
3220
  const res = await fetch(url, {
3216
3221
  method: "POST",
3217
3222
  headers: { "Content-Type": "application/json" },
@@ -6126,7 +6131,7 @@ var init_server = __esm({
6126
6131
  res.writeHead(200, { "Content-Type": "application/json" });
6127
6132
  res.end(JSON.stringify({
6128
6133
  status: "ok",
6129
- version: "1.4.7",
6134
+ version: "1.4.8",
6130
6135
  uptime: process.uptime(),
6131
6136
  clients: this.clients.size,
6132
6137
  agents: this.engines.size
@@ -6238,7 +6243,7 @@ var init_server = __esm({
6238
6243
  const hello = {
6239
6244
  type: "hello",
6240
6245
  protocol: PROTOCOL_VERSION,
6241
- version: "1.4.7",
6246
+ version: "1.4.8",
6242
6247
  agents: this.config.agents.list.map((a) => ({
6243
6248
  id: a.id,
6244
6249
  name: a.name || a.id,
@@ -7632,7 +7637,7 @@ async function runTui(opts) {
7632
7637
  ws.on("open", () => {
7633
7638
  ws.send(JSON.stringify({
7634
7639
  type: "connect",
7635
- params: { auth: { token }, mode: "tui", version: "1.4.7" }
7640
+ params: { auth: { token }, mode: "tui", version: "1.4.8" }
7636
7641
  }));
7637
7642
  });
7638
7643
  ws.on("message", (data) => {
@@ -8061,7 +8066,7 @@ import { fileURLToPath as fileURLToPath5 } from "url";
8061
8066
  import { dirname as dirname5, join as join19 } from "path";
8062
8067
  var __filename3 = fileURLToPath5(import.meta.url);
8063
8068
  var __dirname3 = dirname5(__filename3);
8064
- var version = "1.4.7";
8069
+ var version = "1.4.8";
8065
8070
  try {
8066
8071
  const pkg = JSON.parse(readFileSync(join19(__dirname3, "..", "package.json"), "utf-8"));
8067
8072
  version = pkg.version;