@fugood/bricks-project 2.24.0-beta.15 → 2.24.0-beta.17

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.
@@ -772,6 +772,20 @@ export const templateActionNameMap = {
772
772
  documents: 'GENERATOR_RERANKER_DOCUMENTS',
773
773
  },
774
774
  },
775
+ GENERATOR_MLX_LLM: {
776
+ GENERATOR_MLX_LLM_LOAD_MODEL: {
777
+ modelId: 'GENERATOR_MLX_LLM_MODEL_ID',
778
+ vlm: 'GENERATOR_MLX_LLM_VLM',
779
+ },
780
+ GENERATOR_MLX_LLM_COMPLETION: {
781
+ messages: 'GENERATOR_MLX_LLM_MESSAGES',
782
+ tools: 'GENERATOR_MLX_LLM_TOOLS',
783
+ maxTokens: 'GENERATOR_MLX_LLM_MAX_TOKENS',
784
+ temperature: 'GENERATOR_MLX_LLM_TEMPERATURE',
785
+ topP: 'GENERATOR_MLX_LLM_TOP_P',
786
+ repetitionPenalty: 'GENERATOR_MLX_LLM_REPETITION_PENALTY',
787
+ },
788
+ },
775
789
  GENERATOR_QNN_LLM: {
776
790
  GENERATOR_QNN_LLM_PROCESS: {
777
791
  prompt: 'GENERATOR_QNN_LLM_PROMPT',
package/compile/index.ts CHANGED
@@ -266,6 +266,7 @@ const compileApplicationSettings = (settings: Application['settings']) => ({
266
266
  use_gemini_api_key_system_data: settings.ai.useGeminiApiKeySystemData,
267
267
  }
268
268
  : undefined,
269
+ hide_short_refs: settings?.hideShortRefs,
269
270
  })
270
271
 
271
272
  const animationTypeMap = {
@@ -385,6 +386,7 @@ function compileRunArray(run: unknown[]): unknown[] {
385
386
  const compileTestCase = (testCase: TestCase) => ({
386
387
  id: testCase.id,
387
388
  name: testCase.name,
389
+ hide_short_ref: testCase.hideShortRef,
388
390
  run: compileRunArray(testCase.run),
389
391
  exit_on_failed: testCase.exit_on_failed,
390
392
  commented: testCase.commented,
@@ -449,6 +451,7 @@ const compileAutomationTest = (
449
451
  return {
450
452
  id: testId,
451
453
  title: test.title,
454
+ hide_short_ref: test.hideShortRef,
452
455
  timeout: test.timeout,
453
456
  trigger_type: test.trigger_type,
454
457
  cron: test.cron,
@@ -476,6 +479,7 @@ const compileAutomationTestMap = (testMap: AutomationTestMap, mapId: string) =>
476
479
 
477
480
  return {
478
481
  title: testMap.title,
482
+ hide_short_ref: testMap.hideShortRef,
479
483
  createdAt: testMap.createdAt,
480
484
  map: arrayToIdMap(
481
485
  testMap.tests,
@@ -519,6 +523,7 @@ export const compile = async (app: Application) => {
519
523
  subspaceMap[subspaceId] = {
520
524
  title: subspace.title,
521
525
  description: subspace.description,
526
+ hide_short_ref: subspace.hideShortRef,
522
527
  _expanded: subspace.unexpanded
523
528
  ? {
524
529
  brick: !subspace.unexpanded.brick,
@@ -556,8 +561,10 @@ export const compile = async (app: Application) => {
556
561
  if (animation.__typename === 'Animation') {
557
562
  const animationDef = animation as AnimationDef
558
563
  map[animationId] = {
564
+ alias: animationDef.alias,
559
565
  title: animationDef.title,
560
566
  description: animationDef.description,
567
+ hide_short_ref: animationDef.hideShortRef,
561
568
  animationRunType: animationDef.runType,
562
569
  property: animationDef.property,
563
570
  type: animationTypeMap[animationDef.config.__type],
@@ -569,8 +576,10 @@ export const compile = async (app: Application) => {
569
576
  } else if (animation.__typename === 'AnimationCompose') {
570
577
  const animationDef = animation as AnimationComposeDef
571
578
  map[animationId] = {
579
+ alias: animationDef.alias,
572
580
  title: animationDef.title,
573
581
  description: animationDef.description,
582
+ hide_short_ref: animationDef.hideShortRef,
574
583
  animationRunType: animationDef.runType,
575
584
  compose_type: animationDef.composeType,
576
585
  item_list: animationDef.items.map((item, index) => {
@@ -670,6 +679,8 @@ export const compile = async (app: Application) => {
670
679
  buildList(item, index, 'brickList'),
671
680
  )
672
681
  property.brickList = brickList
682
+ } else if (!brickItems.brickList) {
683
+ property.brickList = []
673
684
  } else {
674
685
  // Not supported Data for brickList
675
686
  throw new TypeError('Not supported Data for brickList directly')
@@ -679,6 +690,8 @@ export const compile = async (app: Application) => {
679
690
  buildList(item, index, 'brickDetails'),
680
691
  )
681
692
  property.brickDetails = brickDetails
693
+ } else if (!brickItems.brickDetails) {
694
+ property.brickDetails = []
682
695
  } else {
683
696
  // Not supported Data for brickList
684
697
  throw new TypeError('Not supported Data for brickList directly')
@@ -686,8 +699,10 @@ export const compile = async (app: Application) => {
686
699
  }
687
700
  map[brickId] = {
688
701
  template_key: brick.templateKey,
702
+ alias: brick.alias,
689
703
  title: brick.title,
690
704
  description: brick.description,
705
+ hide_short_ref: brick.hideShortRef,
691
706
  property,
692
707
  animation: compileAnimations(
693
708
  brick.templateKey,
@@ -754,8 +769,10 @@ export const compile = async (app: Application) => {
754
769
  )
755
770
 
756
771
  map[canvasId] = {
772
+ alias: canvas.alias,
757
773
  title: canvas.title,
758
774
  description: canvas.description,
775
+ hide_short_ref: canvas.hideShortRef,
759
776
  property: compileProperty(
760
777
  canvas.property,
761
778
  `(canvas: ${canvasId}, subspace ${subspaceId})`,
@@ -834,8 +851,10 @@ export const compile = async (app: Application) => {
834
851
 
835
852
  map[generatorId] = {
836
853
  template_key: generator.templateKey,
854
+ alias: generator.alias,
837
855
  title: generator.title,
838
856
  description: generator.description,
857
+ hide_short_ref: generator.hideShortRef,
839
858
  local_sync: generator.localSyncRunMode
840
859
  ? {
841
860
  run_mode: generator.localSyncRunMode,
@@ -904,8 +923,10 @@ export const compile = async (app: Application) => {
904
923
  )
905
924
 
906
925
  map[dataId] = {
926
+ alias: data.alias,
907
927
  title: data.title,
908
928
  description: data.description,
929
+ hide_short_ref: data.hideShortRef,
909
930
  linked: data.metadata?.linked,
910
931
  linkedFrom: data.metadata?.linkedFrom,
911
932
  local_sync: data.localSyncUpdateMode
@@ -939,6 +960,7 @@ export const compile = async (app: Application) => {
939
960
  const calc: any = {
940
961
  title: dataCalc.title,
941
962
  description: dataCalc.description,
963
+ hide_short_ref: dataCalc.hideShortRef,
942
964
  }
943
965
  if (dataCalc.triggerMode) calc.trigger_type = dataCalc.triggerMode
944
966
  if (dataCalc.__typename === 'DataCalculationMap') {
@@ -1025,6 +1047,7 @@ export const compile = async (app: Application) => {
1025
1047
  acc[getNodeId(dataNode, 'data node', nodeIndex)] = {
1026
1048
  title: dataNode.title,
1027
1049
  description: dataNode.description,
1050
+ hide_short_ref: dataNode.hideShortRef,
1028
1051
  type: 'data-node',
1029
1052
  properties: {},
1030
1053
  in: generateInputPorts(dataNode.inputs),
@@ -1050,6 +1073,7 @@ export const compile = async (app: Application) => {
1050
1073
  acc[getNodeId(commandNode, 'command node', nodeIndex)] = {
1051
1074
  title: commandNode.title,
1052
1075
  description: commandNode.description,
1076
+ hide_short_ref: commandNode.hideShortRef,
1053
1077
  type: `command-node-${type}`,
1054
1078
  properties: {
1055
1079
  command: commandNode.__commandName,
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@fugood/bricks-project",
3
- "version": "2.24.0-beta.15",
3
+ "version": "2.24.0-beta.17",
4
4
  "main": "index.ts",
5
5
  "scripts": {
6
6
  "typecheck": "tsc --noEmit",
7
7
  "build": "bun scripts/build.js"
8
8
  },
9
9
  "dependencies": {
10
- "@fugood/bricks-cli": "^2.24.0-beta.15",
10
+ "@fugood/bricks-cli": "^2.24.0-beta.17",
11
11
  "@huggingface/gguf": "^0.3.2",
12
12
  "@iarna/toml": "^3.0.0",
13
13
  "@modelcontextprotocol/sdk": "^1.15.0",
@@ -24,5 +24,5 @@
24
24
  "peerDependencies": {
25
25
  "oxfmt": "^0.36.0"
26
26
  },
27
- "gitHead": "acd51daff8ae31ef803c59b974dfe55fa21af9ed"
27
+ "gitHead": "d99917a2e6eacce97d527fee3c2d6c5bbdcfeef5"
28
28
  }
@@ -37,6 +37,13 @@ Built-in commands for direct state and UI changes.
37
37
  ### Data Calculation (Priority 4)
38
38
  ONLY for deriving, formatting, or aggregating values from other data. Not for orchestration, side effects, or flow control.
39
39
 
40
+ ## Entity Aliases
41
+
42
+ Set `alias` on entities to give them a stable, human-readable name:
43
+ - Code generation uses alias as the variable name (e.g., `alias: 'submitBtn'` → `export const submitBtn`)
44
+ - At runtime, devtools MCP tools accept alias instead of short ID and selectors can match by alias. Note: bricks-project does not directly interact with devtools MCP — aliases here primarily affect code generation
45
+ - Aliases must be unique across the application — duplicates are excluded from resolution
46
+
40
47
  ## Flow Decomposition
41
48
 
42
49
  When the user describes a complex flow, decompose it BEFORE writing code:
@@ -14,8 +14,9 @@ When mobile devices or embedded systems lack hardware for local AI inference (LL
14
14
 
15
15
  ## Supported Generators
16
16
 
17
- - [LLM (GGML)](generator_LLM) - Local Large Language Model inference
18
- - [Speech-to-Text (GGML)](generator_SpeechInference) - Local Speech-to-Text inference
17
+ - LLM (GGML) (LlmMlx.ts) - Local Large Language Model inference with GGML
18
+ - LLM (MLX) (LlmGgml.ts) - Local Large Language Model inference with MLX
19
+ - Speech-to-Text (GGML) (SpeechToTextGgml.ts) - Local Speech-to-Text inference with GGML
19
20
 
20
21
  ## Client Configuration
21
22
 
@@ -50,10 +51,12 @@ const llmGenerator: GeneratorLLM = {
50
51
  property: {
51
52
  modelUrl: 'https://huggingface.co/ggml-org/gemma-3-12b-it-qat-GGUF/resolve/main/gemma-3-12b-it-qat-q4_0.gguf',
52
53
  contextSize: 8192,
53
- buttressEnabled: true,
54
- buttressUrl: 'http://192.168.1.100:2080',
55
- buttressFallbackType: 'use-local',
56
- buttressStrategy: 'prefer-best',
54
+ buttressConnectionSettings: {
55
+ enabled: true,
56
+ url: 'http://192.168.1.100:2080',
57
+ fallbackType: 'use-local',
58
+ strategy: 'prefer-best',
59
+ },
57
60
  },
58
61
  events: {},
59
62
  switches: [],
@@ -102,6 +102,7 @@ type HFSibling = {
102
102
  rfilename: string
103
103
  size?: number
104
104
  lfs?: { sha256?: string }
105
+ blobId?: string
105
106
  }
106
107
 
107
108
  type HFModel = {
@@ -132,8 +133,9 @@ type GeneratorType =
132
133
  | 'GeneratorOnnxLLM'
133
134
  | 'GeneratorOnnxSTT'
134
135
  | 'GeneratorTTS'
136
+ | 'GeneratorMlxLLM'
135
137
 
136
- type ModelKind = 'gguf' | 'onnx'
138
+ type ModelKind = 'gguf' | 'onnx' | 'mlx'
137
139
 
138
140
  interface GeneratorConfig {
139
141
  modelKind: ModelKind
@@ -219,6 +221,11 @@ const generatorConfigs: Record<GeneratorType, GeneratorConfig> = {
219
221
  filter: 'onnx,text-to-speech',
220
222
  hasValidStructure: hasValidOnnxStructure,
221
223
  },
224
+ GeneratorMlxLLM: {
225
+ modelKind: 'mlx',
226
+ filter: 'mlx',
227
+ taskFilter: supportedLlmTasks,
228
+ },
222
229
  }
223
230
 
224
231
  const searchHFModels = async (filter: string, search?: string, limit = 50): Promise<HFModel[]> => {
@@ -276,6 +283,7 @@ export function register(server: McpServer) {
276
283
  'GeneratorOnnxLLM',
277
284
  'GeneratorOnnxSTT',
278
285
  'GeneratorTTS',
286
+ 'GeneratorMlxLLM',
279
287
  ])
280
288
  .describe('Generator type to search models for')
281
289
  .default('GeneratorLLM'),
@@ -407,6 +415,7 @@ export function register(server: McpServer) {
407
415
  'GeneratorOnnxLLM',
408
416
  'GeneratorOnnxSTT',
409
417
  'GeneratorTTS',
418
+ 'GeneratorMlxLLM',
410
419
  ])
411
420
  .describe('Generator type for model selection')
412
421
  .default('GeneratorLLM'),
@@ -489,7 +498,107 @@ export function register(server: McpServer) {
489
498
 
490
499
  // Return JSON for huggingface_select to allow direct parsing by consumers
491
500
  return {
492
- content: [{ type: 'text', text: JSON5.stringify(result, null, 2) }],
501
+ content: [
502
+ {
503
+ type: 'text',
504
+ text: `${JSON5.stringify(result, null, 2)} // Please use _hfRepoInfo undocumented field with @ts-ignore`,
505
+ },
506
+ ],
507
+ }
508
+ }
509
+
510
+ // Handle MLX models (repo-level, like ONNX)
511
+ if (config.modelKind === 'mlx') {
512
+ // Fetch config.json for model architecture metadata
513
+ const headers: Record<string, string> = {}
514
+ if (HF_TOKEN) headers['Authorization'] = `Bearer ${HF_TOKEN}`
515
+ let mlxModelConfig: Record<string, any> | null = null
516
+ try {
517
+ const configRes = await fetch(
518
+ `https://huggingface.co/${modelId}/resolve/main/config.json`,
519
+ { headers },
520
+ )
521
+ if (configRes.ok) mlxModelConfig = await configRes.json()
522
+ } catch {
523
+ // Non-critical
524
+ }
525
+
526
+ const modelType =
527
+ mlxModelConfig?.model_type || details.config?.model_type || details.cardData?.model_type
528
+
529
+ // Build MLX model metadata from config.json (for hardware guardrails)
530
+ const cfg = mlxModelConfig || ({} as Record<string, any>)
531
+ const textCfg = cfg.text_config || cfg
532
+ const numHeads = textCfg.num_attention_heads || textCfg.n_heads || 0
533
+ const hiddenSize = textCfg.hidden_size || textCfg.dim || 0
534
+ const kvLoraRank = textCfg.kv_lora_rank || 0
535
+ const quant = cfg.quantization || cfg.quantization_config || null
536
+
537
+ // Sum safetensors/npz file sizes for model weight bytes
538
+ const modelBytes = siblings
539
+ .filter((f) => /\.(safetensors|npz)$/.test(f.rfilename))
540
+ .reduce((sum, f) => sum + (f.size ?? 0), 0)
541
+
542
+ // Build _mlxDownloadFiles list (safetensors, json, jinja, tokenizer.model)
543
+ const mlxDownloadFiles = siblings
544
+ .filter(
545
+ (f) =>
546
+ f.rfilename.endsWith('.safetensors') ||
547
+ f.rfilename.endsWith('.json') ||
548
+ f.rfilename.endsWith('.jinja') ||
549
+ f.rfilename === 'tokenizer.model',
550
+ )
551
+ .map((f) => ({
552
+ url: `https://huggingface.co/${modelId}/resolve/main/${f.rfilename}?download=true`,
553
+ filename: `${modelId.replace('/', '-')}/${f.rfilename}`,
554
+ hash_type: f.lfs ? 'sha256' : f.blobId ? 'sha1' : undefined,
555
+ sha256: f.lfs?.sha256,
556
+ sha1: f.lfs ? undefined : f.blobId,
557
+ }))
558
+
559
+ const result = {
560
+ modelId,
561
+ modelType,
562
+ _mlxDownloadFiles: mlxDownloadFiles,
563
+ _hfRepoInfo: {
564
+ repo: modelId,
565
+ model: {
566
+ id: details.id,
567
+ downloads: details.downloads,
568
+ likes: details.likes,
569
+ author: details.author,
570
+ },
571
+ generatorType,
572
+ modelType,
573
+ ...(modelBytes > 0 && { size: modelBytes }),
574
+ ...(mlxModelConfig && {
575
+ mlxModelMetadata: {
576
+ hiddenSize,
577
+ numLayers: textCfg.num_hidden_layers || textCfg.n_layers || 0,
578
+ numHeads,
579
+ numKvHeads: textCfg.num_key_value_heads ?? numHeads,
580
+ headDim:
581
+ textCfg.head_dim ||
582
+ textCfg.v_head_dim ||
583
+ (numHeads > 0 && hiddenSize > 0 ? hiddenSize / numHeads : 0),
584
+ maxCtx: textCfg.max_position_embeddings || 0,
585
+ kvLoraRank,
586
+ qkRopeHeadDim: textCfg.qk_rope_head_dim || 0,
587
+ isMLA: kvLoraRank > 0,
588
+ quantBits: quant?.bits || null,
589
+ quantGroupSize: quant?.group_size || null,
590
+ },
591
+ }),
592
+ },
593
+ }
594
+
595
+ return {
596
+ content: [
597
+ {
598
+ type: 'text',
599
+ text: `${JSON5.stringify(result, null, 2)} // IMPORTANT: Use _mlxDownloadFiles / _hfRepoInfo undocumented fields with @ts-ignore`,
600
+ },
601
+ ],
493
602
  }
494
603
  }
495
604
 
@@ -638,7 +747,7 @@ export function register(server: McpServer) {
638
747
  content: [
639
748
  {
640
749
  type: 'text',
641
- text: `${JSON5.stringify(result, null, 2)} // Please use _hfRepoInfo undocumented field with @ts-ignore`,
750
+ text: `${JSON5.stringify(result, null, 2)} // IMPORTANT: Use _hfRepoInfo undocumented field with @ts-ignore`,
642
751
  },
643
752
  ],
644
753
  }
@@ -61,8 +61,10 @@ export interface AnimationDecayConfig {
61
61
  export interface AnimationDef {
62
62
  __typename: 'Animation'
63
63
  id: string
64
+ alias?: string
64
65
  title: string
65
66
  description?: string
67
+ hideShortRef?: boolean
66
68
  runType?: 'once' | 'loop'
67
69
  property:
68
70
  | 'transform.translateX'
@@ -80,8 +82,10 @@ export interface AnimationDef {
80
82
  export interface AnimationComposeDef {
81
83
  __typename: 'AnimationCompose'
82
84
  id: string
85
+ alias?: string
83
86
  title: string
84
87
  description?: string
88
+ hideShortRef?: boolean
85
89
  runType?: 'once' | 'loop'
86
90
  composeType: 'parallel' | 'sequence'
87
91
  items: Array<() => Animation>
@@ -182,6 +182,7 @@ export interface TestCase {
182
182
  __typename: 'TestCase'
183
183
  id: string
184
184
  name: string
185
+ hideShortRef?: boolean
185
186
  run: TestMethodRun
186
187
  exit_on_failed: boolean
187
188
  commented: boolean
@@ -203,6 +204,7 @@ export interface AutomationTest {
203
204
  __typename: 'AutomationTest'
204
205
  id: string
205
206
  title: string
207
+ hideShortRef?: boolean
206
208
  timeout: number
207
209
  trigger_type?: TestTriggerType
208
210
  cron?: string // Cron expression when trigger_type is 'cron'
@@ -220,6 +222,7 @@ export interface AutomationTestMap {
220
222
  __typename: 'AutomationTestMap'
221
223
  id: string
222
224
  title: string
225
+ hideShortRef?: boolean
223
226
  createdAt: number
224
227
  tests: AutomationTest[]
225
228
  }
@@ -188,7 +188,7 @@ Default property:
188
188
  }
189
189
  }
190
190
 
191
- /* Camera view brick ([Tutorial](https://intercom.help/bricks-dag-inc/articles/5378589-camera)) */
191
+ /* Camera view brick */
192
192
  export type BrickCamera = Brick &
193
193
  BrickCameraDef & {
194
194
  templateKey: 'BRICK_CAMERA'
@@ -87,7 +87,7 @@ Default property:
87
87
  }
88
88
  }
89
89
 
90
- /* Image brick ([Tutorial](https://intercom.help/bricks-dag-inc/articles/5378576-image)) */
90
+ /* Image brick */
91
91
  export type BrickImage = Brick &
92
92
  BrickImageDef & {
93
93
  templateKey: 'BRICK_IMAGE'
@@ -137,7 +137,7 @@ Default property:
137
137
  }
138
138
  }
139
139
 
140
- /* Lottie Adobe After Effects animations brick ([Tutorial](https://intercom.help/bricks-dag-inc/articles/5378583-lottie)) */
140
+ /* Lottie Adobe After Effects animations brick */
141
141
  export type BrickLottie = Brick &
142
142
  BrickLottieDef & {
143
143
  templateKey: 'BRICK_LOTTIE'
@@ -231,7 +231,7 @@ Default property:
231
231
  }
232
232
  }
233
233
 
234
- /* Maps brick ([Tutorial](https://intercom.help/bricks-dag-inc/articles/maps)) */
234
+ /* Maps brick */
235
235
  export type BrickMaps = Brick &
236
236
  BrickMapsDef & {
237
237
  templateKey: 'BRICK_MAPS'
@@ -90,7 +90,7 @@ Default property:
90
90
  }
91
91
  }
92
92
 
93
- /* QRCode brick ([Tutorial](https://intercom.help/bricks-dag-inc/articles/5378579-qr-code)) */
93
+ /* QRCode brick */
94
94
  export type BrickQrcode = Brick &
95
95
  BrickQrcodeDef & {
96
96
  templateKey: 'BRICK_QRCODE'
@@ -88,7 +88,7 @@ Default property:
88
88
  }
89
89
  }
90
90
 
91
- /* Rect brick ([Tutorial](https://intercom.help/bricks-dag-inc/articles/5378573-rect)) */
91
+ /* Rect brick */
92
92
  export type BrickRect = Brick &
93
93
  BrickRectDef & {
94
94
  templateKey: 'BRICK_RECT'
@@ -168,7 +168,7 @@ Default property:
168
168
  }
169
169
  }
170
170
 
171
- /* Slideshow brick ([Tutorial](https://intercom.help/bricks-dag-inc/articles/5378580-slideshow)) */
171
+ /* Slideshow brick */
172
172
  export type BrickSlideshow = Brick &
173
173
  BrickSlideshowDef & {
174
174
  templateKey: 'BRICK_SLIDESHOW'
@@ -121,7 +121,7 @@ Default property:
121
121
  }
122
122
  }
123
123
 
124
- /* Text brick ([Tutorial](https://intercom.help/bricks-dag-inc/articles/5378574-text)) */
124
+ /* Text brick */
125
125
  export type BrickText = Brick &
126
126
  BrickTextDef & {
127
127
  templateKey: 'BRICK_TEXT'
@@ -209,7 +209,7 @@ Default property:
209
209
  }
210
210
  }
211
211
 
212
- /* Text Input brick ([Tutorial](https://intercom.help/bricks-dag-inc/articles/5378575-text-input)) */
212
+ /* Text Input brick */
213
213
  export type BrickTextInput = Brick &
214
214
  BrickTextInputDef & {
215
215
  templateKey: 'BRICK_TEXT_INPUT'
@@ -148,7 +148,7 @@ Default property:
148
148
  }
149
149
  }
150
150
 
151
- /* Video brick ([Tutorial](https://intercom.help/bricks-dag-inc/articles/5378577-video)) */
151
+ /* Video brick */
152
152
  export type BrickVideo = Brick &
153
153
  BrickVideoDef & {
154
154
  templateKey: 'BRICK_VIDEO'
@@ -141,7 +141,7 @@ Default property:
141
141
  }
142
142
  }
143
143
 
144
- /* WebView brick ([Tutorial](https://intercom.help/bricks-dag-inc/articles/5378588-web-view)) */
144
+ /* WebView brick */
145
145
  export type BrickWebView = Brick &
146
146
  BrickWebViewDef & {
147
147
  templateKey: 'BRICK_WEBVIEW'
package/types/canvas.ts CHANGED
@@ -36,8 +36,10 @@ interface CanvasDef {
36
36
  export type Canvas = CanvasDef & {
37
37
  __typename: 'Canvas'
38
38
  id: string
39
+ alias?: string
39
40
  title?: string
40
41
  description?: string
42
+ hideShortRef?: boolean
41
43
  switches?: Array<
42
44
  SwitchDef &
43
45
  CanvasDef & {
package/types/common.ts CHANGED
@@ -6,9 +6,11 @@ import type { AutomationMap } from './automation'
6
6
  export interface Brick {
7
7
  __typename: 'Brick'
8
8
  id: string
9
+ alias?: string
9
10
  templateKey: string
10
11
  title?: string
11
12
  description?: string
13
+ hideShortRef?: boolean
12
14
  property?: {}
13
15
  events: {}
14
16
  outlets?: {}
@@ -24,9 +26,11 @@ export enum LocalSyncStrategy {
24
26
  export interface Generator {
25
27
  __typename: 'Generator'
26
28
  id: string
29
+ alias?: string
27
30
  templateKey: string
28
31
  title?: string
29
32
  description?: string
33
+ hideShortRef?: boolean
30
34
  localSyncRunMode?: LocalSyncStrategy
31
35
  property?: {}
32
36
  events: {}
@@ -121,6 +125,7 @@ export type ApplicationSettings = {
121
125
  useOpenAiApiKeySystemData?: boolean
122
126
  useGeminiApiKeySystemData?: boolean
123
127
  }
128
+ hideShortRefs?: boolean
124
129
  }
125
130
 
126
131
  export type Application = {
@@ -6,6 +6,7 @@ export interface DataCalculationData {
6
6
  __typename: 'DataCalculationData'
7
7
  title?: string
8
8
  description?: string
9
+ hideShortRef?: boolean
9
10
  data: () => Data
10
11
  inputs: Array<{
11
12
  key: 'change'
@@ -26,6 +27,7 @@ export interface DataCommand {
26
27
  id: string
27
28
  title?: string
28
29
  description?: string
30
+ hideShortRef?: boolean
29
31
  inputs: Array<{
30
32
  key: string
31
33
  source: (() => DataCalculationData | DataCommand) | any
@@ -4,6 +4,7 @@ export interface DataCalculation {
4
4
  id: string
5
5
  title?: string
6
6
  description?: string
7
+ hideShortRef?: boolean
7
8
  // Auto: Run the calculation when inputs change and allow triggers. Careful with circular dependencies!
8
9
  // Manual: Only run the calculation when manually triggered by System Action PROPERTY_BANK_COMMAND
9
10
  triggerMode?: 'auto' | 'manual'
package/types/data.ts CHANGED
@@ -17,8 +17,10 @@ interface DataDef {
17
17
  export type Data<T = any> = DataDef & {
18
18
  __typename: 'Data'
19
19
  id: string
20
+ alias?: string
20
21
  title: string
21
22
  description?: string
23
+ hideShortRef?: boolean
22
24
  metadata?: {
23
25
  linked?: Array<SubspaceID>
24
26
  linkedFrom?: SubspaceID
@@ -434,7 +434,7 @@ Default property:
434
434
  | DataLink
435
435
  /* Whether to cache messages */
436
436
  cacheMessages?: boolean | DataLink
437
- /* LLM Generator (Supports `LLM (GGML)` and `OpenAI LLM` generators) */
437
+ /* LLM Generator (Supports `LLM (GGML)`, `LLM (MLX)`, and `OpenAI LLM` generators) */
438
438
  llmGeneratorId?: string | DataLink | (() => Generator)
439
439
  /* LLM Live Policy. If the policy is `only-in-use`, the LLM context will be released when the assistant is not in use.
440
440
 
@@ -0,0 +1,210 @@
1
+ /* Auto generated by build script */
2
+ import type { SwitchCondInnerStateCurrentCanvas, SwitchCondData, SwitchDef } from '../switch'
3
+ import type { Data, DataLink } from '../data'
4
+ import type {
5
+ Brick,
6
+ Generator,
7
+ EventAction,
8
+ ActionWithDataParams,
9
+ ActionWithParams,
10
+ Action,
11
+ EventProperty,
12
+ } from '../common'
13
+
14
+ /* Load model */
15
+ export type GeneratorMlxLLMActionLoadModel = ActionWithParams & {
16
+ __actionName: 'GENERATOR_MLX_LLM_LOAD_MODEL'
17
+ params?: Array<
18
+ | {
19
+ input: 'modelId'
20
+ value?: string | DataLink | EventProperty
21
+ mapping?: string
22
+ }
23
+ | {
24
+ input: 'vlm'
25
+ value?: boolean | DataLink | EventProperty
26
+ mapping?: string
27
+ }
28
+ >
29
+ }
30
+
31
+ /* Run text completion */
32
+ export type GeneratorMlxLLMActionCompletion = ActionWithParams & {
33
+ __actionName: 'GENERATOR_MLX_LLM_COMPLETION'
34
+ params?: Array<
35
+ | {
36
+ input: 'messages'
37
+ value?: Array<any> | DataLink | EventProperty
38
+ mapping?: string
39
+ }
40
+ | {
41
+ input: 'tools'
42
+ value?: Array<any> | DataLink | EventProperty
43
+ mapping?: string
44
+ }
45
+ | {
46
+ input: 'maxTokens'
47
+ value?: number | DataLink | EventProperty
48
+ mapping?: string
49
+ }
50
+ | {
51
+ input: 'temperature'
52
+ value?: number | DataLink | EventProperty
53
+ mapping?: string
54
+ }
55
+ | {
56
+ input: 'topP'
57
+ value?: number | DataLink | EventProperty
58
+ mapping?: string
59
+ }
60
+ | {
61
+ input: 'repetitionPenalty'
62
+ value?: number | DataLink | EventProperty
63
+ mapping?: string
64
+ }
65
+ >
66
+ }
67
+
68
+ /* Stop text completion */
69
+ export type GeneratorMlxLLMActionStopCompletion = Action & {
70
+ __actionName: 'GENERATOR_MLX_LLM_STOP_COMPLETION'
71
+ }
72
+
73
+ /* Release model context */
74
+ export type GeneratorMlxLLMActionReleaseContext = Action & {
75
+ __actionName: 'GENERATOR_MLX_LLM_RELEASE_CONTEXT'
76
+ }
77
+
78
+ interface GeneratorMlxLLMDef {
79
+ /*
80
+ Default property:
81
+ {
82
+ "init": false,
83
+ "modelId": "mlx-community/Qwen3-4B-4bit",
84
+ "vlm": false,
85
+ "completionMessages": [
86
+ {
87
+ "role": "system",
88
+ "content": "You are a helpful assistant."
89
+ },
90
+ {
91
+ "role": "user",
92
+ "content": "Hello"
93
+ }
94
+ ],
95
+ "completionMaxTokens": 1024,
96
+ "completionTemperature": 0.6,
97
+ "completionTopP": 1,
98
+ "completionRepetitionContextSize": 20
99
+ }
100
+ */
101
+ property?: {
102
+ /* Initialize model on generator init */
103
+ init?: boolean | DataLink
104
+ /* HuggingFace model ID or local path to model directory
105
+ e.g. "mlx-community/Qwen3-4B-4bit" */
106
+ modelId?: string | DataLink
107
+ /* Enable Vision Language Model (VLM) mode */
108
+ vlm?: boolean | DataLink
109
+ /* Chat messages (if first message has role 'system', it will be used as system prompt) */
110
+ completionMessages?:
111
+ | Array<
112
+ | DataLink
113
+ | {
114
+ role?: string | DataLink
115
+ content?: string | DataLink
116
+ }
117
+ >
118
+ | DataLink
119
+ /* Maximum tokens to generate */
120
+ completionMaxTokens?: number | DataLink
121
+ /* Temperature (0.0 to 2.0) */
122
+ completionTemperature?: number | DataLink
123
+ /* Top P sampling */
124
+ completionTopP?: number | DataLink
125
+ /* Repetition penalty factor */
126
+ completionRepetitionPenalty?: number | DataLink
127
+ /* Number of tokens to consider for repetition penalty */
128
+ completionRepetitionContextSize?: number | DataLink
129
+ /* Maximum KV cache size (context window). Uses rotating cache to limit memory.
130
+ Smaller values (e.g. 512) use less memory but lower quality.
131
+ Larger values (e.g. 4096) use more memory but better quality.
132
+ Leave empty for unlimited (model default). */
133
+ contextSize?: number | DataLink
134
+ /* Enable thinking mode (model-dependent, e.g. Qwen3).
135
+ When enabled, passes enable_thinking=true to the chat template.
136
+ The model may output reasoning in &lt;think&gt; tags which will be extracted as reasoning_content. */
137
+ completionEnableThinking?: boolean | DataLink
138
+ /* Additional keyword arguments for chat template (object) */
139
+ completionChatTemplateKwargs?: {} | DataLink
140
+ /* Tools for chat mode using OpenAI-compatible function calling format
141
+ Format: Array of objects with {type, function: {name, description, parameters}} structure
142
+ See: https://platform.openai.com/docs/guides/function-calling */
143
+ completionTools?: Array<{} | DataLink> | DataLink
144
+ /* Buttress connection settings for remote inference */
145
+ buttressConnectionSettings?:
146
+ | DataLink
147
+ | {
148
+ enabled?: boolean | DataLink
149
+ url?: string | DataLink
150
+ fallbackType?: 'use-local' | 'no-op' | DataLink
151
+ strategy?: 'prefer-local' | 'prefer-buttress' | 'prefer-best' | DataLink
152
+ }
153
+ }
154
+ events?: {
155
+ /* Event triggered when context state changes */
156
+ onContextStateChange?: Array<EventAction>
157
+ /* Error event */
158
+ onError?: Array<EventAction>
159
+ /* Completion streaming event (emitted for each token) */
160
+ onCompletion?: Array<EventAction>
161
+ /* Completion finished event */
162
+ onCompletionFinished?: Array<EventAction>
163
+ }
164
+ outlets?: {
165
+ /* Context state */
166
+ contextState?: () => Data
167
+ /* Model load progress (0-1) */
168
+ loadProgress?: () => Data
169
+ /* Whether the model is evaluating */
170
+ isEvaluating?: () => Data
171
+ /* Completion result */
172
+ completionResult?: () => Data
173
+ /* Last token */
174
+ completionLastToken?: () => Data
175
+ }
176
+ }
177
+
178
+ /* On-device LLM inference using Apple MLX framework on iOS/tvOS
179
+
180
+ ## Features
181
+ - Powered by MLX (Apple's ML framework optimized for Apple Silicon)
182
+ - Download models directly from HuggingFace Hub
183
+ - Streaming token generation
184
+ - Supports LLM and VLM (Vision Language Models)
185
+ - Requires iOS 17+ or tvOS 17+ */
186
+ export type GeneratorMlxLLM = Generator &
187
+ GeneratorMlxLLMDef & {
188
+ templateKey: 'GENERATOR_MLX_LLM'
189
+ switches?: Array<
190
+ SwitchDef &
191
+ GeneratorMlxLLMDef & {
192
+ conds?: Array<{
193
+ method: '==' | '!=' | '>' | '<' | '>=' | '<='
194
+ cond:
195
+ | SwitchCondInnerStateCurrentCanvas
196
+ | SwitchCondData
197
+ | {
198
+ __typename: 'SwitchCondInnerStateOutlet'
199
+ outlet:
200
+ | 'contextState'
201
+ | 'loadProgress'
202
+ | 'isEvaluating'
203
+ | 'completionResult'
204
+ | 'completionLastToken'
205
+ value: any
206
+ }
207
+ }>
208
+ }
209
+ >
210
+ }
@@ -44,6 +44,7 @@ export * from './RealtimeTranscription'
44
44
  export * from './LlmGgml'
45
45
  export * from './TextToSpeechGgml'
46
46
  export * from './RerankerGgml'
47
+ export * from './LlmMlx'
47
48
  export * from './LlmQualcommAiEngine'
48
49
  export * from './LlmOpenAiCompat'
49
50
  export * from './TextToSpeechOpenAiLike'
package/types/subspace.ts CHANGED
@@ -9,6 +9,7 @@ export type Subspace = {
9
9
  id: string
10
10
  title: string
11
11
  description?: string
12
+ hideShortRef?: boolean
12
13
  // Unexpanded information in Editor
13
14
  unexpanded?: {
14
15
  data?: boolean
@@ -905,6 +905,22 @@ export const templateEventPropsMap = {
905
905
  'GENERATOR_RERANKER_ERROR', // type: string
906
906
  ],
907
907
  },
908
+ GENERATOR_MLX_LLM: {
909
+ onContextStateChange: [
910
+ 'GENERATOR_MLX_LLM_CONTEXT_STATE', // type: string
911
+ ],
912
+ onError: [
913
+ 'GENERATOR_MLX_LLM_ERROR', // type: string
914
+ ],
915
+ onCompletion: [
916
+ 'GENERATOR_MLX_LLM_COMPLETION_TOKEN', // type: string
917
+ 'GENERATOR_MLX_LLM_COMPLETION_RESULT', // type: string
918
+ ],
919
+ onCompletionFinished: [
920
+ 'GENERATOR_MLX_LLM_COMPLETION_RESULT', // type: string
921
+ 'GENERATOR_MLX_LLM_COMPLETION_RESULT_DETAILS', // type: object
922
+ ],
923
+ },
908
924
  GENERATOR_QNN_LLM: {
909
925
  onContextStateChange: [
910
926
  'GENERATOR_QNN_LLM_CONTEXT_STATE', // type: string