@bendyline/gezel-inference 1.0.7 → 1.0.9

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.
Files changed (78) hide show
  1. package/dist/catalog/chat-models/ge/gemma4-12b-q4/manifest.json +46 -3
  2. package/dist/catalog/chat-models/ge/gemma4-12b-q4/versions/1.2.1/manifest.json +141 -0
  3. package/dist/catalog/chat-models/ge/gemma4-e4b-q4/manifest.json +5 -0
  4. package/dist/catalog/chat-models/index.json +1 -1
  5. package/dist/catalog/chat-models/or/ornith1.5-9b-q4/manifest.json +5 -0
  6. package/dist/catalog/chat-models/or/ornith1.5-9b-q8/manifest.json +5 -0
  7. package/dist/catalog/chat-models/qw/qwen3.5-9b-q4/manifest.json +5 -0
  8. package/dist/catalog/chat-models/qw/qwen3.8-27b-q4/manifest.json +5 -0
  9. package/dist/catalog/chat-models/qw/qwen3.8-flash-next-q2/manifest.json +24 -7
  10. package/dist/catalog/chat-models/qw/qwen3.8-flash-next-q2/versions/1.0.3/manifest.json +47 -0
  11. package/dist/catalog/chat-models/raw-index.json +1 -1
  12. package/dist/catalog/provenance.json +1 -1
  13. package/dist/engines/electron-native-reuse.d.ts +5 -4
  14. package/dist/engines/electron-native-reuse.js +1 -1
  15. package/dist/engines/native-file-manifest.json +12344 -698
  16. package/dist/engines/native-manifest.d.ts +4 -4
  17. package/dist/engines/native-manifest.js +40 -36
  18. package/dist/engines/resolver.d.ts +18 -17
  19. package/dist/engines/resolver.js +36 -1
  20. package/dist/http/model-inventory-cache.d.ts +1 -1
  21. package/dist/http/routes/engines.js +3 -3
  22. package/dist/http/routes/v1-images.d.ts +2 -1
  23. package/dist/http/routes/v1-images.js +36 -9
  24. package/dist/knowledge/manager.d.ts +3 -27
  25. package/dist/knowledge/manager.js +8 -364
  26. package/dist/knowledge/unified-search.d.ts +61 -0
  27. package/dist/knowledge/unified-search.js +373 -0
  28. package/dist/models/catalog-drift.d.ts +2 -0
  29. package/dist/models/catalog-drift.js +1 -1
  30. package/dist/models/catalog-payload-identity.d.ts +2 -2
  31. package/dist/models/catalog-payload-identity.js +10 -5
  32. package/dist/providers/active-install-message.js +1 -1
  33. package/dist/providers/catalog-model-config.d.ts +28 -0
  34. package/dist/providers/ds4/build-provider.js +35 -13
  35. package/dist/providers/ds4/residency.d.ts +77 -0
  36. package/dist/providers/ds4/residency.js +87 -6
  37. package/dist/providers/image/sd-cpp.js +19 -11
  38. package/dist/providers/llama-cpp/backend-health.d.ts +3 -2
  39. package/dist/providers/llama-cpp/backend-health.js +6 -3
  40. package/dist/providers/llama-cpp/backend-quarantine.js +1 -1
  41. package/dist/providers/llama-cpp/build-provider.js +168 -29
  42. package/dist/providers/llama-cpp/devices.js +4 -1
  43. package/dist/providers/llama-cpp/engine-flags.d.ts +8 -1
  44. package/dist/providers/llama-cpp/engine-flags.js +13 -8
  45. package/dist/providers/llama-cpp/gpu-startup-watch.d.ts +4 -4
  46. package/dist/providers/llama-cpp/gpu-startup-watch.js +7 -5
  47. package/dist/providers/llama-cpp/models.d.ts +10 -0
  48. package/dist/providers/llama-cpp/models.js +64 -10
  49. package/dist/providers/llama-cpp/offload-planner.d.ts +6 -0
  50. package/dist/providers/llama-cpp/offload-planner.js +1 -1
  51. package/dist/providers/llama-cpp/spec-draft.d.ts +45 -23
  52. package/dist/providers/llama-cpp/spec-draft.js +113 -24
  53. package/dist/providers/mlx/async-file-handoff.d.ts +9 -1
  54. package/dist/providers/mlx/async-file-handoff.js +32 -4
  55. package/dist/providers/mlx/provider.js +28 -16
  56. package/dist/providers/mlx/python/spec_decode.py +23 -2
  57. package/dist/providers/mlx/python/tool_args_json.py +59 -21
  58. package/dist/providers/mlx/runtime-diagnostics.d.ts +6 -0
  59. package/dist/providers/mlx/runtime-diagnostics.js +18 -1
  60. package/dist/providers/mlx/tool-call-protocol.d.ts +4 -3
  61. package/dist/providers/mlx/tool-call-protocol.js +4 -3
  62. package/dist/providers/mlx/venv.d.ts +19 -1
  63. package/dist/providers/mlx/venv.js +21 -2
  64. package/dist/providers/native/device-capacity-ledger.d.ts +4 -2
  65. package/dist/providers/native/device-capacity-ledger.js +35 -20
  66. package/dist/providers/native/device-capacity.d.ts +4 -0
  67. package/dist/providers/native/device-capacity.js +5 -0
  68. package/dist/providers/native/local-engine-runtime.d.ts +16 -1
  69. package/dist/providers/native/local-engine-runtime.js +142 -39
  70. package/dist/providers/native/process-identity.d.ts +38 -0
  71. package/dist/providers/native/process-identity.js +86 -0
  72. package/dist/providers/native/supervisor.d.ts +8 -1
  73. package/dist/providers/native/supervisor.js +16 -7
  74. package/dist/providers/types.d.ts +4 -0
  75. package/dist/remotes/types.d.ts +1 -1
  76. package/dist/runtime-lock.d.ts +3 -27
  77. package/dist/runtime-lock.js +7 -80
  78. package/package.json +4 -4
@@ -1,6 +1,6 @@
1
- import { readFileSync, readlinkSync } from 'node:fs';
2
1
  import { mkdir, open, readFile, rm, stat, utimes } from 'node:fs/promises';
3
- import { hostname as osHostname } from 'node:os';
2
+ import { LOCK_HEARTBEAT_INTERVAL_MS, LOCK_STALE_AFTER_MS, currentLockIdentity, foreignHolderMessage, parseLockFile, procStartTicks, sharesPidNamespace, } from '@bendyline/gezel/native';
3
+ export { currentLockIdentity, parseLockFile, procStartTicks, sharesPidNamespace };
4
4
  /**
5
5
  * Thrown when a gezel home already has a live daemon. The CLI's `gezel
6
6
  * start` / the supervisor surface this as an actionable message rather
@@ -12,7 +12,7 @@ export class SingleInstanceError extends Error {
12
12
  holderHost;
13
13
  constructor(holderPid, lockPath, holderHost) {
14
14
  super(holderHost !== undefined
15
- ? `Another Gezel daemon (host "${holderHost}", pid ${holderPid}) is using this home. If it runs in a container, run commands inside that container with \`docker exec <container> gezel …\` instead of starting a second container on the same volume.`
15
+ ? foreignHolderMessage({ pid: holderPid, hostname: holderHost })
16
16
  : holderPid > 0
17
17
  ? `Another gezel daemon is already running for this home (pid ${holderPid}). Stop it first with \`gezel stop\`, or use a different GEZEL_HOME.`
18
18
  : `Could not acquire the single-instance lock at ${lockPath}.`);
@@ -22,8 +22,8 @@ export class SingleInstanceError extends Error {
22
22
  this.name = 'SingleInstanceError';
23
23
  }
24
24
  }
25
- const HEARTBEAT_INTERVAL_MS = 10_000;
26
- const STALE_AFTER_MS = 40_000;
25
+ // A holder's identity (core's lock-identity.ts) is what let a one-shot
26
+ // `docker run … gezel do` stop reclaiming a serving container's live lock.
27
27
  function defaultIsAlive(pid) {
28
28
  try {
29
29
  process.kill(pid, 0);
@@ -35,45 +35,6 @@ function defaultIsAlive(pid) {
35
35
  return err.code === 'EPERM';
36
36
  }
37
37
  }
38
- function readTrimmed(path) {
39
- try {
40
- return readFileSync(path, 'utf8').trim() || undefined;
41
- }
42
- catch {
43
- return undefined;
44
- }
45
- }
46
- export function procStartTicks(pid) {
47
- if (process.platform !== 'linux')
48
- return undefined;
49
- const stat = readTrimmed(`/proc/${pid}/stat`);
50
- if (!stat)
51
- return undefined;
52
- // comm (field 2) may contain spaces and parentheses; fields resume after
53
- // the last ')'. starttime is field 22 overall, the 20th after comm.
54
- const rest = stat.slice(stat.lastIndexOf(')') + 2).split(' ');
55
- return rest[19];
56
- }
57
- export function currentLockIdentity() {
58
- const linux = process.platform === 'linux';
59
- let pidNs;
60
- if (linux) {
61
- try {
62
- pidNs = readlinkSync('/proc/self/ns/pid');
63
- }
64
- catch {
65
- pidNs = undefined;
66
- }
67
- }
68
- return {
69
- pid: process.pid,
70
- hostname: osHostname(),
71
- bootId: linux ? readTrimmed('/proc/sys/kernel/random/boot_id') : undefined,
72
- pidNs,
73
- startTicks: procStartTicks('self'),
74
- instance: `${process.pid}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`,
75
- };
76
- }
77
38
  /**
78
39
  * The pid stays on the first line so a daemon from before the identity
79
40
  * record (which parses the leading integer) still reads it as held instead
@@ -82,29 +43,6 @@ export function currentLockIdentity() {
82
43
  function serializeIdentity(identity) {
83
44
  return `${identity.pid}\n${JSON.stringify({ v: 1, ...identity })}\n`;
84
45
  }
85
- export function parseLockFile(text) {
86
- const [first, second] = text.split('\n');
87
- const pid = Number.parseInt((first ?? '').trim(), 10);
88
- if (!Number.isFinite(pid))
89
- return null;
90
- if (!second?.trim())
91
- return { pid };
92
- try {
93
- const record = JSON.parse(second);
94
- const text = (value) => (typeof value === 'string' && value ? value : undefined);
95
- return {
96
- pid,
97
- hostname: text(record.hostname),
98
- bootId: text(record.bootId),
99
- pidNs: text(record.pidNs),
100
- startTicks: text(record.startTicks),
101
- instance: text(record.instance),
102
- };
103
- }
104
- catch {
105
- return { pid };
106
- }
107
- }
108
46
  async function readHolder(lockPath) {
109
47
  try {
110
48
  return parseLockFile(await readFile(lockPath, 'utf8'));
@@ -113,17 +51,6 @@ async function readHolder(lockPath) {
113
51
  return null;
114
52
  }
115
53
  }
116
- /**
117
- * Whether a pid check against `holder` means anything here. Any field the
118
- * holder recorded must match ours; a legacy pid-only record is assumed to be
119
- * in our namespace, which is how it was judged before.
120
- */
121
- export function sharesPidNamespace(holder, me) {
122
- const same = (a, b) => !a || !b || a === b;
123
- return (same(holder.hostname, me.hostname) &&
124
- same(holder.bootId, me.bootId) &&
125
- same(holder.pidNs, me.pidNs));
126
- }
127
54
  async function lockMtimeMs(lockPath) {
128
55
  try {
129
56
  return (await stat(lockPath)).mtimeMs;
@@ -174,7 +101,7 @@ export async function acquireSingleInstanceLock(opts) {
174
101
  const startTicksOf = opts.startTicksOf ?? procStartTicks;
175
102
  const now = opts.now ?? Date.now;
176
103
  const sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
177
- const staleAfterMs = opts.staleAfterMs ?? STALE_AFTER_MS;
104
+ const staleAfterMs = opts.staleAfterMs ?? LOCK_STALE_AFTER_MS;
178
105
  await mkdir(opts.runtimeDir, { recursive: true });
179
106
  for (let attempt = 0; attempt < 3; attempt++) {
180
107
  try {
@@ -185,7 +112,7 @@ export async function acquireSingleInstanceLock(opts) {
185
112
  finally {
186
113
  await handle.close();
187
114
  }
188
- return holdLock(opts.lockPath, me, opts.heartbeatIntervalMs ?? HEARTBEAT_INTERVAL_MS);
115
+ return holdLock(opts.lockPath, me, opts.heartbeatIntervalMs ?? LOCK_HEARTBEAT_INTERVAL_MS);
189
116
  }
190
117
  catch (err) {
191
118
  if (err.code !== 'EEXIST')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bendyline/gezel-inference",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Gezel's on-device inference runtime: native engines, local model management, embeddings, knowledge search, and OpenAI-compatible routes.",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -73,9 +73,9 @@
73
73
  "!dist/**/__pycache__"
74
74
  ],
75
75
  "dependencies": {
76
- "@bendyline/gezel": "1.2.12",
77
- "@bendyline/gezel-catalog": "1.2.12",
78
- "@bendyline/gezel-client": "1.2.12",
76
+ "@bendyline/gezel": "1.2.14",
77
+ "@bendyline/gezel-catalog": "1.2.14",
78
+ "@bendyline/gezel-client": "1.2.14",
79
79
  "@bendyline/gezel-knowledge": "1.2.10",
80
80
  "hono": "4.13.14",
81
81
  "tar": "7.5.21",