@agentshouse/kit 0.2.1-c031c7457a661 → 0.2.1-c03721a31074a

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.
@@ -1,23 +1,23 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
- "version": "0.2.1-c031c7457a661",
3
+ "version": "0.2.1-c03721a31074a",
4
4
  "hosts": {
5
5
  "macos": {
6
6
  "asset": {
7
7
  "name": "connect-linux.sh",
8
- "url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-c031c7457a661/connect-linux.sh"
8
+ "url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-c03721a31074a/connect-linux.sh"
9
9
  }
10
10
  },
11
11
  "linux": {
12
12
  "asset": {
13
13
  "name": "connect-linux.sh",
14
- "url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-c031c7457a661/connect-linux.sh"
14
+ "url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-c03721a31074a/connect-linux.sh"
15
15
  }
16
16
  },
17
17
  "windows": {
18
18
  "asset": {
19
19
  "name": "connect-windows.ps1",
20
- "url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-c031c7457a661/connect-windows.ps1"
20
+ "url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-c03721a31074a/connect-windows.ps1"
21
21
  }
22
22
  }
23
23
  }
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- const [major = 0, minor = 0] = process.versions.node.split('.').map(Number);
3
- if (major < 24 || (major === 24 && minor < 14)) {
4
- process.stderr.write(`house: the Kit needs Node 24.14.0 or newer; this is ${process.versions.node}\n`);
2
+ const [major = 0, minor = 0, patch = 0] = process.versions.node.split('.').map(Number);
3
+ if (major < 24 || (major === 24 && (minor < 22 || (minor === 22 && patch < 1)))) {
4
+ process.stderr.write(`house: the Kit needs Node 24.22.1 or newer; this is ${process.versions.node}\n`);
5
5
  process.exitCode = 1;
6
6
  }
7
7
  else {
package/dist/kit-main.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- const [major = 0, minor = 0] = process.versions.node.split('.').map(Number);
3
- if (major < 24 || (major === 24 && minor < 14)) {
4
- process.stderr.write(`kit: the Kit needs Node 24.14.0 or newer; this is ${process.versions.node}\n`);
2
+ const [major = 0, minor = 0, patch = 0] = process.versions.node.split('.').map(Number);
3
+ if (major < 24 || (major === 24 && (minor < 22 || (minor === 22 && patch < 1)))) {
4
+ process.stderr.write(`kit: the Kit needs Node 24.22.1 or newer; this is ${process.versions.node}\n`);
5
5
  process.exitCode = 1;
6
6
  }
7
7
  else {
@@ -12,20 +12,21 @@ const RELEASE = 'https://github.com/agentshouse/kit/releases/download/engine-2';
12
12
  export const MODEL = {
13
13
  url: 'https://huggingface.co/ggml-org/parakeet-GGUF/resolve/35156454d1a39de06863303dd209fd2bed6ee079/ggml-parakeet-tdt-0.6b-v3-q4_k.bin',
14
14
  sha256: '8b205b8b39c6535e153de6fb11c51db46125d45c4f16ba496fe41a0fe71b885e',
15
+ bytes: 415_611_879,
15
16
  executable: false,
16
17
  };
17
18
  export const ENGINES = {
18
19
  'linux-x64': {
19
- decoder: { url: `${RELEASE}/ffmpeg-linux-x86_64`, sha256: '1f8235d206428305afb89c6e8ab99d100425a0ba61e22bb4c7aff017db8c8de5', executable: true },
20
- engine: { url: `${RELEASE}/parakeet-cli-linux-x86_64`, sha256: 'bb2585695992fe1927a33960002cdf51b8a90a96ad65593c3d0a9f1fbc0865c2', executable: true },
20
+ decoder: { url: `${RELEASE}/ffmpeg-linux-x86_64`, sha256: '1f8235d206428305afb89c6e8ab99d100425a0ba61e22bb4c7aff017db8c8de5', bytes: 5_175_832, executable: true },
21
+ engine: { url: `${RELEASE}/parakeet-cli-linux-x86_64`, sha256: 'bb2585695992fe1927a33960002cdf51b8a90a96ad65593c3d0a9f1fbc0865c2', bytes: 3_801_616, executable: true },
21
22
  },
22
23
  'linux-arm64': {
23
- decoder: { url: `${RELEASE}/ffmpeg-linux-aarch64`, sha256: 'a7e08a0fae0179d1078312f6bb13d2a9aa4d4c71a1d82a022953f25dee452f5e', executable: true },
24
- engine: { url: `${RELEASE}/parakeet-cli-linux-aarch64`, sha256: 'cbc0bedc8daae97f1ef9dcee4200c06226218e300e0fd62ead1306d22742b7ed', executable: true },
24
+ decoder: { url: `${RELEASE}/ffmpeg-linux-aarch64`, sha256: 'a7e08a0fae0179d1078312f6bb13d2a9aa4d4c71a1d82a022953f25dee452f5e', bytes: 4_590_208, executable: true },
25
+ engine: { url: `${RELEASE}/parakeet-cli-linux-aarch64`, sha256: 'cbc0bedc8daae97f1ef9dcee4200c06226218e300e0fd62ead1306d22742b7ed', bytes: 3_477_624, executable: true },
25
26
  },
26
27
  'darwin-arm64': {
27
- decoder: { url: `${RELEASE}/ffmpeg-darwin-arm64`, sha256: '7abe154aaed3d6b49f5167ca7221bb66bed51388925d99a7e4261a41fe52fba6', executable: true },
28
- engine: { url: `${RELEASE}/parakeet-cli-darwin-arm64`, sha256: '9a2aafc0922ad7c0b6db6eff1641e96572ba32ac40bf995a1df242ed2febf297', executable: true },
28
+ decoder: { url: `${RELEASE}/ffmpeg-darwin-arm64`, sha256: '7abe154aaed3d6b49f5167ca7221bb66bed51388925d99a7e4261a41fe52fba6', bytes: 3_696_768, executable: true },
29
+ engine: { url: `${RELEASE}/parakeet-cli-darwin-arm64`, sha256: '9a2aafc0922ad7c0b6db6eff1641e96572ba32ac40bf995a1df242ed2febf297', bytes: 1_939_728, executable: true },
29
30
  },
30
31
  };
31
32
  const CHUNK_SECONDS = 20;
@@ -46,7 +47,7 @@ function installed(artifact) {
46
47
  return join(directory(), artifact.sha256);
47
48
  }
48
49
  async function executed(command, args, signal) {
49
- // A download or a transcription runs as long as its size needs; the setting turning off or the turn's interrupt or end aborts it instead.
50
+ // A download or a transcription runs as long as its size needs; a download's deadline, the setting turning off or the turn's interrupt or end aborts it instead.
50
51
  const ran = await run(command, args, 0, false, signal);
51
52
  if (ran.status !== 0)
52
53
  throw new Error(failureOf(ran, basename(command)));
@@ -99,8 +100,20 @@ async function install(artifacts, signal) {
99
100
  try {
100
101
  for (const artifact of missing) {
101
102
  const part = `${installed(artifact)}.part`;
103
+ // An artifact arrives at a hundred kilobytes a second or its download ends, so a stalled host cannot hold the install open.
104
+ const deadlineMs = Math.ceil(artifact.bytes / 100);
105
+ const deadline = AbortSignal.timeout(deadlineMs);
102
106
  // Three retries carry a large download past a dropped connection before the download fails.
103
- await executed('curl', ['-fsSL', '--retry', '3', '-o', part, artifact.url], signal);
107
+ try {
108
+ await executed('bash', ['-c', 'trap "" XFSZ && ulimit -f "$1" && exec curl -fsSL --retry 3 -o "$2" "$3"', 'bash', String(Math.ceil(artifact.bytes / 1024)), part, artifact.url], AbortSignal.any([signal, deadline]));
109
+ }
110
+ catch (error) {
111
+ if (((await stat(part).catch(() => null))?.size ?? 0) >= artifact.bytes)
112
+ throw new Error(`${artifact.url} is larger than its pinned ${artifact.bytes} bytes`);
113
+ if (deadline.aborted && !signal.aborted)
114
+ throw new Error(`${artifact.url} did not arrive within ${Math.ceil(deadlineMs / 1000)} seconds`);
115
+ throw error;
116
+ }
104
117
  if ((await sha256(part)) !== artifact.sha256)
105
118
  throw new Error(`${artifact.url} does not match its sha256`);
106
119
  }
package/dist/update.js CHANGED
@@ -6,6 +6,9 @@ import { join } from 'node:path';
6
6
  import { run } from './clis.js';
7
7
  import { kitHome, workspaceRoot } from './home.js';
8
8
  import { service, throughSudo } from './placement.js';
9
+ const BOOTSTRAP_BYTES = 1_000_000;
10
+ // A bootstrap is at most a million bytes, so two minutes carry it over ten kilobytes a second and no stalled host holds the update queue.
11
+ const BOOTSTRAP_MS = 120_000;
9
12
  function directory() {
10
13
  return join(kitHome(), 'update');
11
14
  }
@@ -66,6 +69,17 @@ async function finished(callId) {
66
69
  await new Promise((resolve) => setTimeout(resolve, 1000));
67
70
  }
68
71
  }
72
+ async function bounded(body, most) {
73
+ const chunks = [];
74
+ let bytes = 0;
75
+ for await (const chunk of body ?? []) {
76
+ bytes += chunk.length;
77
+ if (bytes > most)
78
+ return null;
79
+ chunks.push(chunk);
80
+ }
81
+ return Buffer.concat(chunks, bytes);
82
+ }
69
83
  function rerun(script, callId, flags) {
70
84
  return new Promise((resolve) => {
71
85
  const [command, ...args] = [
@@ -119,10 +133,21 @@ export class KitUpdate {
119
133
  async carry(call) {
120
134
  if ((await pendingCall()) === call.input_id)
121
135
  return finished(call.input_id);
122
- const answer = await fetch(call.bootstrap);
123
- if (!answer.ok)
124
- return { refused: `the Kit bootstrap could not be downloaded: ${answer.status}` };
125
- const script = Buffer.from(await answer.arrayBuffer());
136
+ const deadline = AbortSignal.timeout(BOOTSTRAP_MS);
137
+ let script;
138
+ try {
139
+ const answer = await fetch(call.bootstrap, { signal: deadline });
140
+ if (!answer.ok)
141
+ return { refused: `the Kit bootstrap could not be downloaded: ${answer.status}` };
142
+ script = await bounded(answer.body, BOOTSTRAP_BYTES);
143
+ }
144
+ catch (error) {
145
+ if (!deadline.aborted)
146
+ throw error;
147
+ return { refused: `the Kit bootstrap did not arrive within ${BOOTSTRAP_MS / 1000} seconds` };
148
+ }
149
+ if (script === null)
150
+ return { refused: `the Kit bootstrap is larger than ${BOOTSTRAP_BYTES} bytes` };
126
151
  if (createHash('sha256').update(script).digest('hex') !== call.sha256) {
127
152
  return { refused: 'the Kit bootstrap does not match its sha256' };
128
153
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentshouse/kit",
3
- "version": "0.2.1-c031c7457a661",
3
+ "version": "0.2.1-c03721a31074a",
4
4
  "description": "Kit connects an Environment to agents.house.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -50,20 +50,20 @@
50
50
  "vitest": "5.0.1",
51
51
  "ws": "8.22.0"
52
52
  },
53
- "packageManager": "npm@11.19.0",
53
+ "packageManager": "npm@11.19.1",
54
54
  "engines": {
55
- "node": "24.21.0",
56
- "npm": "11.19.0"
55
+ "node": "24.22.1",
56
+ "npm": "11.19.1"
57
57
  },
58
58
  "devEngines": {
59
59
  "runtime": {
60
60
  "name": "node",
61
- "version": "24.21.0",
61
+ "version": "24.22.1",
62
62
  "onFail": "error"
63
63
  },
64
64
  "packageManager": {
65
65
  "name": "npm",
66
- "version": "11.19.0",
66
+ "version": "11.19.1",
67
67
  "onFail": "error"
68
68
  }
69
69
  }