@camstack/addon-ai 0.4.52 → 0.4.54

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 (3) hide show
  1. package/dist/addon.js +149 -40
  2. package/dist/addon.mjs +149 -40
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -7921,7 +7921,8 @@ var OpsLogReasonSchema = _enum([
7921
7921
  "quota",
7922
7922
  "manual",
7923
7923
  "operator",
7924
- "maintenance"
7924
+ "maintenance",
7925
+ "orphaned-device"
7925
7926
  ]);
7926
7927
  /** One audit row, shared verbatim by both domains. */
7927
7928
  var OpsLogEntrySchema = object({
@@ -12952,10 +12953,39 @@ var DevicePersistConfigPayloadSchema = object({
12952
12953
  deviceId: number$1(),
12953
12954
  data: record(string(), unknown())
12954
12955
  });
12956
+ /** What a migration actually did, per switch. `unreachable` is a first-class
12957
+ * answer: a camera that could not be asked is not a camera that was silenced. */
12958
+ var MigrateSwitchOutcomeSchema = _enum([
12959
+ "off",
12960
+ "on",
12961
+ "not-offered",
12962
+ "unreachable"
12963
+ ]);
12964
+ var MigrateSwitchReportSchema = object({
12965
+ deviceId: number$1(),
12966
+ switchId: CameraSwitchIdSchema,
12967
+ outcome: MigrateSwitchOutcomeSchema,
12968
+ detail: string().optional()
12969
+ });
12970
+ var MigrateDeviceResultSchema = object({
12971
+ sourceId: number$1(),
12972
+ targetId: number$1(),
12973
+ switches: array(MigrateSwitchReportSchema).readonly(),
12974
+ /** Switches that could NOT be turned off on the source. Empty is the only
12975
+ * value meaning the replaced hardware is quiet. */
12976
+ sourceStillLive: array(CameraSwitchIdSchema).readonly(),
12977
+ swapped: boolean()
12978
+ });
12955
12979
  method(object({
12956
12980
  addonId: string(),
12957
12981
  stableId: string()
12958
- }), object({ id: number$1() }), { kind: "mutation" }), method(DeviceRegisterPayloadSchema, _void(), { kind: "mutation" }), method(DeviceRemovePayloadSchema, _void(), { kind: "mutation" }), method(DevicePersistConfigPayloadSchema, _void(), { kind: "mutation" }), method(object({ deviceId: number$1() }), record(string(), unknown())), method(object({ deviceId: number$1() }), record(string(), unknown())), method(object({ deviceId: number$1() }), DeviceMetaSchema.nullable()), method(object({
12982
+ }), object({ id: number$1() }), { kind: "mutation" }), method(object({
12983
+ sourceId: number$1(),
12984
+ targetId: number$1()
12985
+ }), MigrateDeviceResultSchema, {
12986
+ kind: "mutation",
12987
+ auth: "admin"
12988
+ }), method(DeviceRegisterPayloadSchema, _void(), { kind: "mutation" }), method(DeviceRemovePayloadSchema, _void(), { kind: "mutation" }), method(DevicePersistConfigPayloadSchema, _void(), { kind: "mutation" }), method(object({ deviceId: number$1() }), record(string(), unknown())), method(object({ deviceId: number$1() }), record(string(), unknown())), method(object({ deviceId: number$1() }), DeviceMetaSchema.nullable()), method(object({
12959
12989
  deviceId: number$1(),
12960
12990
  name: string()
12961
12991
  }), _void(), {
@@ -30552,6 +30582,12 @@ Object.freeze({
30552
30582
  addonId: null,
30553
30583
  access: "view"
30554
30584
  },
30585
+ "deviceManager.migrateDevice": {
30586
+ capName: "device-manager",
30587
+ capScope: "system",
30588
+ addonId: null,
30589
+ access: "create"
30590
+ },
30555
30591
  "deviceManager.persistConfig": {
30556
30592
  capName: "device-manager",
30557
30593
  capScope: "system",
@@ -73825,6 +73861,10 @@ var CONSUMER_RETRY_POLICY = {
73825
73861
  "ai-summary": RETRYING,
73826
73862
  /** NcConfirmGate — 8 s total budget, fail-OPEN. */
73827
73863
  "notifier-rules": NOT_RETRYING,
73864
+ /** NcRuleAiAnalyst — the sentence on ONE notification, same 8 s budget and
73865
+ * the same reason: somebody is holding a phone, and a retry produces a
73866
+ * later notification rather than a better one. */
73867
+ "notifier-narration": NOT_RETRYING,
73828
73868
  /** SceneConfirmGate + checkSceneLlm — 8 s total budget, fail-CLOSED. */
73829
73869
  "scene-monitor": NOT_RETRYING
73830
73870
  };
@@ -74735,43 +74775,6 @@ var LLAMA = textEntry({
74735
74775
  minRamBytes: Math.round(3.5 * GIB),
74736
74776
  contextSizeDefault: 4096
74737
74777
  });
74738
- var SMOLVLM_MODEL_BYTES = 1112602656;
74739
- var SMOLVLM_MMPROJ_BYTES = 872303680;
74740
- var SMOLVLM_MMPROJ_URL = "https://huggingface.co/ggml-org/SmolVLM2-2.2B-Instruct-GGUF/resolve/main/mmproj-SmolVLM2-2.2B-Instruct-f16.gguf";
74741
- var SMOLVLM = {
74742
- meta: {
74743
- id: "llm-smolvlm2-2.2b-instruct-q4",
74744
- label: "SmolVLM2 2.2B Instruct (vision)",
74745
- family: "smolvlm2",
74746
- purpose: "vision",
74747
- url: "https://huggingface.co/ggml-org/SmolVLM2-2.2B-Instruct-GGUF/resolve/main/SmolVLM2-2.2B-Instruct-Q4_K_M.gguf",
74748
- sha256: "0cf76814555b8665149075b74ab6b5c1d428ea1d3d01c1918c12012e8d7c9f58",
74749
- sizeBytes: SMOLVLM_MODEL_BYTES,
74750
- quantization: "Q4_K_M",
74751
- minRamBytes: 4 * GIB,
74752
- contextSizeDefault: 4096,
74753
- mmprojUrl: SMOLVLM_MMPROJ_URL
74754
- },
74755
- entry: {
74756
- id: "llm-smolvlm2-2.2b-instruct-q4",
74757
- name: "SmolVLM2 2.2B Instruct (vision)",
74758
- description: "smolvlm2 · Q4_K_M · +mmproj",
74759
- formats: { gguf: {
74760
- url: "https://huggingface.co/ggml-org/SmolVLM2-2.2B-Instruct-GGUF/resolve/main/SmolVLM2-2.2B-Instruct-Q4_K_M.gguf",
74761
- sizeMB: mb(SMOLVLM_MODEL_BYTES)
74762
- } },
74763
- inputSize: {
74764
- width: 0,
74765
- height: 0
74766
- },
74767
- labels: [],
74768
- extraFiles: [{
74769
- url: SMOLVLM_MMPROJ_URL,
74770
- filename: "mmproj-SmolVLM2-2.2B-Instruct-f16.gguf",
74771
- sizeMB: mb(SMOLVLM_MMPROJ_BYTES)
74772
- }]
74773
- }
74774
- };
74775
74778
  var QWEN3VL2B_MODEL_BYTES = 1107410624;
74776
74779
  var QWEN3VL2B_MMPROJ_BYTES = 819395232;
74777
74780
  var QWEN3VL2B_BASE = "https://huggingface.co/unsloth/Qwen3-VL-2B-Instruct-GGUF/resolve/main";
@@ -74818,6 +74821,111 @@ var QWEN3VL_2B = {
74818
74821
  }]
74819
74822
  }
74820
74823
  };
74824
+ var QWEN3VL4B_MODEL_BYTES = 2497282336;
74825
+ var QWEN3VL4B_MMPROJ_BYTES = 836180640;
74826
+ var QWEN3VL4B_BASE = "https://huggingface.co/unsloth/Qwen3-VL-4B-Instruct-GGUF/resolve/main";
74827
+ var QWEN3VL4B_MMPROJ_URL = `${QWEN3VL4B_BASE}/mmproj-F16.gguf`;
74828
+ var QWEN3VL4B_URL = `${QWEN3VL4B_BASE}/Qwen3-VL-4B-Instruct-Q4_K_M.gguf`;
74829
+ /**
74830
+ * The middle rung. It exists because the catalogue used to jump from 2B to a
74831
+ * 35B MoE, and the operator was running an 8B through an EXTERNAL LM Studio
74832
+ * endpoint precisely because nothing in between was offered here — the gap was
74833
+ * pushing the work outside the addon that is supposed to own it.
74834
+ *
74835
+ * At ~3.3 GB all in, this is also the only tier above 2B that a small
74836
+ * mini-PC-class node can hold, so the ladder is now 2B → 4B → 8B rather than
74837
+ * 2B → nothing.
74838
+ *
74839
+ * Same `qwen3vl_merger` projector as the 2B and the 8B: one prompt set and one
74840
+ * download shape cover all three. That is the reason this family was chosen
74841
+ * over its neighbours, not a benchmark — Gemma 4 and GLM-4.6V each want a
74842
+ * projector this addon has never exercised, for no verified gain at this size.
74843
+ */
74844
+ var QWEN3VL_4B = {
74845
+ meta: {
74846
+ id: "llm-qwen3-vl-4b-instruct-q4",
74847
+ label: "Qwen3-VL 4B Instruct (vision)",
74848
+ family: "qwen3-vl",
74849
+ purpose: "vision",
74850
+ url: QWEN3VL4B_URL,
74851
+ sha256: "d4dcd426bfba75752a312b266b80fec8136fbaca13c62d93b7ac41fa67f0492b",
74852
+ sizeBytes: QWEN3VL4B_MODEL_BYTES,
74853
+ quantization: "Q4_K_M",
74854
+ minRamBytes: 5 * GIB,
74855
+ contextSizeDefault: 8192,
74856
+ mmprojUrl: QWEN3VL4B_MMPROJ_URL
74857
+ },
74858
+ entry: {
74859
+ id: "llm-qwen3-vl-4b-instruct-q4",
74860
+ name: "Qwen3-VL 4B Instruct (vision)",
74861
+ description: "qwen3-vl · Q4_K_M · +mmproj",
74862
+ formats: { gguf: {
74863
+ url: QWEN3VL4B_URL,
74864
+ sizeMB: mb(QWEN3VL4B_MODEL_BYTES)
74865
+ } },
74866
+ inputSize: {
74867
+ width: 0,
74868
+ height: 0
74869
+ },
74870
+ labels: [],
74871
+ extraFiles: [{
74872
+ url: QWEN3VL4B_MMPROJ_URL,
74873
+ filename: "mmproj-F16.gguf",
74874
+ sizeMB: mb(QWEN3VL4B_MMPROJ_BYTES)
74875
+ }]
74876
+ }
74877
+ };
74878
+ var QWEN3VL8B_MODEL_BYTES = 5027785568;
74879
+ var QWEN3VL8B_MMPROJ_BYTES = 1159030336;
74880
+ var QWEN3VL8B_BASE = "https://huggingface.co/unsloth/Qwen3-VL-8B-Instruct-GGUF/resolve/main";
74881
+ var QWEN3VL8B_MMPROJ_URL = `${QWEN3VL8B_BASE}/mmproj-F16.gguf`;
74882
+ var QWEN3VL8B_URL = `${QWEN3VL8B_BASE}/Qwen3-VL-8B-Instruct-Q4_K_M.gguf`;
74883
+ /**
74884
+ * The tier the operator already trusts, brought in-house.
74885
+ *
74886
+ * This is the same weight class as the `qwen/qwen3-vl-8b` served by an external
74887
+ * LM Studio endpoint on the Mac: as a `managed-local` profile the addon owns
74888
+ * the runtime and `nodePin` puts the INFERENCE on that node, instead of the hub
74889
+ * calling out over HTTP to a process nobody here supervises.
74890
+ *
74891
+ * ~6.2 GB resident is a real bite on a 16 GB machine shared with the rest of
74892
+ * CamStack — that is what `minRamBytes` is for, and it is why the 4B above
74893
+ * exists rather than this being the only new rung.
74894
+ */
74895
+ var QWEN3VL_8B = {
74896
+ meta: {
74897
+ id: "llm-qwen3-vl-8b-instruct-q4",
74898
+ label: "Qwen3-VL 8B Instruct (vision)",
74899
+ family: "qwen3-vl",
74900
+ purpose: "vision",
74901
+ url: QWEN3VL8B_URL,
74902
+ sha256: "108e7ff92b78eefd3db4741885104acba514255c11b617d3c7b197a5f46efe89",
74903
+ sizeBytes: QWEN3VL8B_MODEL_BYTES,
74904
+ quantization: "Q4_K_M",
74905
+ minRamBytes: 8 * GIB,
74906
+ contextSizeDefault: 8192,
74907
+ mmprojUrl: QWEN3VL8B_MMPROJ_URL
74908
+ },
74909
+ entry: {
74910
+ id: "llm-qwen3-vl-8b-instruct-q4",
74911
+ name: "Qwen3-VL 8B Instruct (vision)",
74912
+ description: "qwen3-vl · Q4_K_M · +mmproj",
74913
+ formats: { gguf: {
74914
+ url: QWEN3VL8B_URL,
74915
+ sizeMB: mb(QWEN3VL8B_MODEL_BYTES)
74916
+ } },
74917
+ inputSize: {
74918
+ width: 0,
74919
+ height: 0
74920
+ },
74921
+ labels: [],
74922
+ extraFiles: [{
74923
+ url: QWEN3VL8B_MMPROJ_URL,
74924
+ filename: "mmproj-F16.gguf",
74925
+ sizeMB: mb(QWEN3VL8B_MMPROJ_BYTES)
74926
+ }]
74927
+ }
74928
+ };
74821
74929
  var QWEN36_MODEL_BYTES = 22134528992;
74822
74930
  var QWEN36_MMPROJ_BYTES = 899283680;
74823
74931
  var QWEN36_BASE = "https://huggingface.co/unsloth/Qwen3.6-35B-A3B-GGUF/resolve/main";
@@ -74826,8 +74934,9 @@ var QWEN36_URL = `${QWEN36_BASE}/Qwen3.6-35B-A3B-UD-Q4_K_M.gguf`;
74826
74934
  var LLM_MODEL_CATALOG = [
74827
74935
  QWEN,
74828
74936
  LLAMA,
74829
- SMOLVLM,
74830
74937
  QWEN3VL_2B,
74938
+ QWEN3VL_4B,
74939
+ QWEN3VL_8B,
74831
74940
  {
74832
74941
  meta: {
74833
74942
  id: "llm-qwen3.6-35b-a3b-ud-q4",
package/dist/addon.mjs CHANGED
@@ -7948,7 +7948,8 @@ var OpsLogReasonSchema = _enum([
7948
7948
  "quota",
7949
7949
  "manual",
7950
7950
  "operator",
7951
- "maintenance"
7951
+ "maintenance",
7952
+ "orphaned-device"
7952
7953
  ]);
7953
7954
  /** One audit row, shared verbatim by both domains. */
7954
7955
  var OpsLogEntrySchema = object({
@@ -12979,10 +12980,39 @@ var DevicePersistConfigPayloadSchema = object({
12979
12980
  deviceId: number$1(),
12980
12981
  data: record(string(), unknown())
12981
12982
  });
12983
+ /** What a migration actually did, per switch. `unreachable` is a first-class
12984
+ * answer: a camera that could not be asked is not a camera that was silenced. */
12985
+ var MigrateSwitchOutcomeSchema = _enum([
12986
+ "off",
12987
+ "on",
12988
+ "not-offered",
12989
+ "unreachable"
12990
+ ]);
12991
+ var MigrateSwitchReportSchema = object({
12992
+ deviceId: number$1(),
12993
+ switchId: CameraSwitchIdSchema,
12994
+ outcome: MigrateSwitchOutcomeSchema,
12995
+ detail: string().optional()
12996
+ });
12997
+ var MigrateDeviceResultSchema = object({
12998
+ sourceId: number$1(),
12999
+ targetId: number$1(),
13000
+ switches: array(MigrateSwitchReportSchema).readonly(),
13001
+ /** Switches that could NOT be turned off on the source. Empty is the only
13002
+ * value meaning the replaced hardware is quiet. */
13003
+ sourceStillLive: array(CameraSwitchIdSchema).readonly(),
13004
+ swapped: boolean()
13005
+ });
12982
13006
  method(object({
12983
13007
  addonId: string(),
12984
13008
  stableId: string()
12985
- }), object({ id: number$1() }), { kind: "mutation" }), method(DeviceRegisterPayloadSchema, _void(), { kind: "mutation" }), method(DeviceRemovePayloadSchema, _void(), { kind: "mutation" }), method(DevicePersistConfigPayloadSchema, _void(), { kind: "mutation" }), method(object({ deviceId: number$1() }), record(string(), unknown())), method(object({ deviceId: number$1() }), record(string(), unknown())), method(object({ deviceId: number$1() }), DeviceMetaSchema.nullable()), method(object({
13009
+ }), object({ id: number$1() }), { kind: "mutation" }), method(object({
13010
+ sourceId: number$1(),
13011
+ targetId: number$1()
13012
+ }), MigrateDeviceResultSchema, {
13013
+ kind: "mutation",
13014
+ auth: "admin"
13015
+ }), method(DeviceRegisterPayloadSchema, _void(), { kind: "mutation" }), method(DeviceRemovePayloadSchema, _void(), { kind: "mutation" }), method(DevicePersistConfigPayloadSchema, _void(), { kind: "mutation" }), method(object({ deviceId: number$1() }), record(string(), unknown())), method(object({ deviceId: number$1() }), record(string(), unknown())), method(object({ deviceId: number$1() }), DeviceMetaSchema.nullable()), method(object({
12986
13016
  deviceId: number$1(),
12987
13017
  name: string()
12988
13018
  }), _void(), {
@@ -30579,6 +30609,12 @@ Object.freeze({
30579
30609
  addonId: null,
30580
30610
  access: "view"
30581
30611
  },
30612
+ "deviceManager.migrateDevice": {
30613
+ capName: "device-manager",
30614
+ capScope: "system",
30615
+ addonId: null,
30616
+ access: "create"
30617
+ },
30582
30618
  "deviceManager.persistConfig": {
30583
30619
  capName: "device-manager",
30584
30620
  capScope: "system",
@@ -73852,6 +73888,10 @@ var CONSUMER_RETRY_POLICY = {
73852
73888
  "ai-summary": RETRYING,
73853
73889
  /** NcConfirmGate — 8 s total budget, fail-OPEN. */
73854
73890
  "notifier-rules": NOT_RETRYING,
73891
+ /** NcRuleAiAnalyst — the sentence on ONE notification, same 8 s budget and
73892
+ * the same reason: somebody is holding a phone, and a retry produces a
73893
+ * later notification rather than a better one. */
73894
+ "notifier-narration": NOT_RETRYING,
73855
73895
  /** SceneConfirmGate + checkSceneLlm — 8 s total budget, fail-CLOSED. */
73856
73896
  "scene-monitor": NOT_RETRYING
73857
73897
  };
@@ -74762,43 +74802,6 @@ var LLAMA = textEntry({
74762
74802
  minRamBytes: Math.round(3.5 * GIB),
74763
74803
  contextSizeDefault: 4096
74764
74804
  });
74765
- var SMOLVLM_MODEL_BYTES = 1112602656;
74766
- var SMOLVLM_MMPROJ_BYTES = 872303680;
74767
- var SMOLVLM_MMPROJ_URL = "https://huggingface.co/ggml-org/SmolVLM2-2.2B-Instruct-GGUF/resolve/main/mmproj-SmolVLM2-2.2B-Instruct-f16.gguf";
74768
- var SMOLVLM = {
74769
- meta: {
74770
- id: "llm-smolvlm2-2.2b-instruct-q4",
74771
- label: "SmolVLM2 2.2B Instruct (vision)",
74772
- family: "smolvlm2",
74773
- purpose: "vision",
74774
- url: "https://huggingface.co/ggml-org/SmolVLM2-2.2B-Instruct-GGUF/resolve/main/SmolVLM2-2.2B-Instruct-Q4_K_M.gguf",
74775
- sha256: "0cf76814555b8665149075b74ab6b5c1d428ea1d3d01c1918c12012e8d7c9f58",
74776
- sizeBytes: SMOLVLM_MODEL_BYTES,
74777
- quantization: "Q4_K_M",
74778
- minRamBytes: 4 * GIB,
74779
- contextSizeDefault: 4096,
74780
- mmprojUrl: SMOLVLM_MMPROJ_URL
74781
- },
74782
- entry: {
74783
- id: "llm-smolvlm2-2.2b-instruct-q4",
74784
- name: "SmolVLM2 2.2B Instruct (vision)",
74785
- description: "smolvlm2 · Q4_K_M · +mmproj",
74786
- formats: { gguf: {
74787
- url: "https://huggingface.co/ggml-org/SmolVLM2-2.2B-Instruct-GGUF/resolve/main/SmolVLM2-2.2B-Instruct-Q4_K_M.gguf",
74788
- sizeMB: mb(SMOLVLM_MODEL_BYTES)
74789
- } },
74790
- inputSize: {
74791
- width: 0,
74792
- height: 0
74793
- },
74794
- labels: [],
74795
- extraFiles: [{
74796
- url: SMOLVLM_MMPROJ_URL,
74797
- filename: "mmproj-SmolVLM2-2.2B-Instruct-f16.gguf",
74798
- sizeMB: mb(SMOLVLM_MMPROJ_BYTES)
74799
- }]
74800
- }
74801
- };
74802
74805
  var QWEN3VL2B_MODEL_BYTES = 1107410624;
74803
74806
  var QWEN3VL2B_MMPROJ_BYTES = 819395232;
74804
74807
  var QWEN3VL2B_BASE = "https://huggingface.co/unsloth/Qwen3-VL-2B-Instruct-GGUF/resolve/main";
@@ -74845,6 +74848,111 @@ var QWEN3VL_2B = {
74845
74848
  }]
74846
74849
  }
74847
74850
  };
74851
+ var QWEN3VL4B_MODEL_BYTES = 2497282336;
74852
+ var QWEN3VL4B_MMPROJ_BYTES = 836180640;
74853
+ var QWEN3VL4B_BASE = "https://huggingface.co/unsloth/Qwen3-VL-4B-Instruct-GGUF/resolve/main";
74854
+ var QWEN3VL4B_MMPROJ_URL = `${QWEN3VL4B_BASE}/mmproj-F16.gguf`;
74855
+ var QWEN3VL4B_URL = `${QWEN3VL4B_BASE}/Qwen3-VL-4B-Instruct-Q4_K_M.gguf`;
74856
+ /**
74857
+ * The middle rung. It exists because the catalogue used to jump from 2B to a
74858
+ * 35B MoE, and the operator was running an 8B through an EXTERNAL LM Studio
74859
+ * endpoint precisely because nothing in between was offered here — the gap was
74860
+ * pushing the work outside the addon that is supposed to own it.
74861
+ *
74862
+ * At ~3.3 GB all in, this is also the only tier above 2B that a small
74863
+ * mini-PC-class node can hold, so the ladder is now 2B → 4B → 8B rather than
74864
+ * 2B → nothing.
74865
+ *
74866
+ * Same `qwen3vl_merger` projector as the 2B and the 8B: one prompt set and one
74867
+ * download shape cover all three. That is the reason this family was chosen
74868
+ * over its neighbours, not a benchmark — Gemma 4 and GLM-4.6V each want a
74869
+ * projector this addon has never exercised, for no verified gain at this size.
74870
+ */
74871
+ var QWEN3VL_4B = {
74872
+ meta: {
74873
+ id: "llm-qwen3-vl-4b-instruct-q4",
74874
+ label: "Qwen3-VL 4B Instruct (vision)",
74875
+ family: "qwen3-vl",
74876
+ purpose: "vision",
74877
+ url: QWEN3VL4B_URL,
74878
+ sha256: "d4dcd426bfba75752a312b266b80fec8136fbaca13c62d93b7ac41fa67f0492b",
74879
+ sizeBytes: QWEN3VL4B_MODEL_BYTES,
74880
+ quantization: "Q4_K_M",
74881
+ minRamBytes: 5 * GIB,
74882
+ contextSizeDefault: 8192,
74883
+ mmprojUrl: QWEN3VL4B_MMPROJ_URL
74884
+ },
74885
+ entry: {
74886
+ id: "llm-qwen3-vl-4b-instruct-q4",
74887
+ name: "Qwen3-VL 4B Instruct (vision)",
74888
+ description: "qwen3-vl · Q4_K_M · +mmproj",
74889
+ formats: { gguf: {
74890
+ url: QWEN3VL4B_URL,
74891
+ sizeMB: mb(QWEN3VL4B_MODEL_BYTES)
74892
+ } },
74893
+ inputSize: {
74894
+ width: 0,
74895
+ height: 0
74896
+ },
74897
+ labels: [],
74898
+ extraFiles: [{
74899
+ url: QWEN3VL4B_MMPROJ_URL,
74900
+ filename: "mmproj-F16.gguf",
74901
+ sizeMB: mb(QWEN3VL4B_MMPROJ_BYTES)
74902
+ }]
74903
+ }
74904
+ };
74905
+ var QWEN3VL8B_MODEL_BYTES = 5027785568;
74906
+ var QWEN3VL8B_MMPROJ_BYTES = 1159030336;
74907
+ var QWEN3VL8B_BASE = "https://huggingface.co/unsloth/Qwen3-VL-8B-Instruct-GGUF/resolve/main";
74908
+ var QWEN3VL8B_MMPROJ_URL = `${QWEN3VL8B_BASE}/mmproj-F16.gguf`;
74909
+ var QWEN3VL8B_URL = `${QWEN3VL8B_BASE}/Qwen3-VL-8B-Instruct-Q4_K_M.gguf`;
74910
+ /**
74911
+ * The tier the operator already trusts, brought in-house.
74912
+ *
74913
+ * This is the same weight class as the `qwen/qwen3-vl-8b` served by an external
74914
+ * LM Studio endpoint on the Mac: as a `managed-local` profile the addon owns
74915
+ * the runtime and `nodePin` puts the INFERENCE on that node, instead of the hub
74916
+ * calling out over HTTP to a process nobody here supervises.
74917
+ *
74918
+ * ~6.2 GB resident is a real bite on a 16 GB machine shared with the rest of
74919
+ * CamStack — that is what `minRamBytes` is for, and it is why the 4B above
74920
+ * exists rather than this being the only new rung.
74921
+ */
74922
+ var QWEN3VL_8B = {
74923
+ meta: {
74924
+ id: "llm-qwen3-vl-8b-instruct-q4",
74925
+ label: "Qwen3-VL 8B Instruct (vision)",
74926
+ family: "qwen3-vl",
74927
+ purpose: "vision",
74928
+ url: QWEN3VL8B_URL,
74929
+ sha256: "108e7ff92b78eefd3db4741885104acba514255c11b617d3c7b197a5f46efe89",
74930
+ sizeBytes: QWEN3VL8B_MODEL_BYTES,
74931
+ quantization: "Q4_K_M",
74932
+ minRamBytes: 8 * GIB,
74933
+ contextSizeDefault: 8192,
74934
+ mmprojUrl: QWEN3VL8B_MMPROJ_URL
74935
+ },
74936
+ entry: {
74937
+ id: "llm-qwen3-vl-8b-instruct-q4",
74938
+ name: "Qwen3-VL 8B Instruct (vision)",
74939
+ description: "qwen3-vl · Q4_K_M · +mmproj",
74940
+ formats: { gguf: {
74941
+ url: QWEN3VL8B_URL,
74942
+ sizeMB: mb(QWEN3VL8B_MODEL_BYTES)
74943
+ } },
74944
+ inputSize: {
74945
+ width: 0,
74946
+ height: 0
74947
+ },
74948
+ labels: [],
74949
+ extraFiles: [{
74950
+ url: QWEN3VL8B_MMPROJ_URL,
74951
+ filename: "mmproj-F16.gguf",
74952
+ sizeMB: mb(QWEN3VL8B_MMPROJ_BYTES)
74953
+ }]
74954
+ }
74955
+ };
74848
74956
  var QWEN36_MODEL_BYTES = 22134528992;
74849
74957
  var QWEN36_MMPROJ_BYTES = 899283680;
74850
74958
  var QWEN36_BASE = "https://huggingface.co/unsloth/Qwen3.6-35B-A3B-GGUF/resolve/main";
@@ -74853,8 +74961,9 @@ var QWEN36_URL = `${QWEN36_BASE}/Qwen3.6-35B-A3B-UD-Q4_K_M.gguf`;
74853
74961
  var LLM_MODEL_CATALOG = [
74854
74962
  QWEN,
74855
74963
  LLAMA,
74856
- SMOLVLM,
74857
74964
  QWEN3VL_2B,
74965
+ QWEN3VL_4B,
74966
+ QWEN3VL_8B,
74858
74967
  {
74859
74968
  meta: {
74860
74969
  id: "llm-qwen3.6-35b-a3b-ud-q4",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-ai",
3
- "version": "0.4.52",
3
+ "version": "0.4.54",
4
4
  "description": "AI addon for CamStack — the `llm` collection provider (cloud, LAN, and camstack-managed local llama.cpp profiles) plus the per-node `llm-runtime` managed executor.",
5
5
  "keywords": [
6
6
  "camstack",