@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.
- package/compile/action-name-map.ts +14 -0
- package/compile/index.ts +24 -0
- package/package.json +3 -3
- package/skills/bricks-project/rules/architecture-patterns.md +7 -0
- package/skills/bricks-project/rules/buttress.md +9 -6
- package/tools/mcp-tools/huggingface.ts +112 -3
- package/types/animation.ts +4 -0
- package/types/automation.ts +3 -0
- package/types/bricks/Camera.ts +1 -1
- package/types/bricks/Image.ts +1 -1
- package/types/bricks/Lottie.ts +1 -1
- package/types/bricks/Maps.ts +1 -1
- package/types/bricks/QrCode.ts +1 -1
- package/types/bricks/Rect.ts +1 -1
- package/types/bricks/Slideshow.ts +1 -1
- package/types/bricks/Text.ts +1 -1
- package/types/bricks/TextInput.ts +1 -1
- package/types/bricks/Video.ts +1 -1
- package/types/bricks/WebView.ts +1 -1
- package/types/canvas.ts +2 -0
- package/types/common.ts +5 -0
- package/types/data-calc-command.ts +2 -0
- package/types/data-calc.ts +1 -0
- package/types/data.ts +2 -0
- package/types/generators/Assistant.ts +1 -1
- package/types/generators/LlmMlx.ts +210 -0
- package/types/generators/index.ts +1 -0
- package/types/subspace.ts +1 -0
- package/utils/event-props.ts +16 -0
|
@@ -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.
|
|
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.
|
|
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": "
|
|
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
|
-
-
|
|
18
|
-
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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: [
|
|
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)} //
|
|
750
|
+
text: `${JSON5.stringify(result, null, 2)} // IMPORTANT: Use _hfRepoInfo undocumented field with @ts-ignore`,
|
|
642
751
|
},
|
|
643
752
|
],
|
|
644
753
|
}
|
package/types/animation.ts
CHANGED
|
@@ -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>
|
package/types/automation.ts
CHANGED
|
@@ -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
|
}
|
package/types/bricks/Camera.ts
CHANGED
|
@@ -188,7 +188,7 @@ Default property:
|
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
-
/* Camera view brick
|
|
191
|
+
/* Camera view brick */
|
|
192
192
|
export type BrickCamera = Brick &
|
|
193
193
|
BrickCameraDef & {
|
|
194
194
|
templateKey: 'BRICK_CAMERA'
|
package/types/bricks/Image.ts
CHANGED
package/types/bricks/Lottie.ts
CHANGED
|
@@ -137,7 +137,7 @@ Default property:
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
/* Lottie Adobe After Effects animations brick
|
|
140
|
+
/* Lottie Adobe After Effects animations brick */
|
|
141
141
|
export type BrickLottie = Brick &
|
|
142
142
|
BrickLottieDef & {
|
|
143
143
|
templateKey: 'BRICK_LOTTIE'
|
package/types/bricks/Maps.ts
CHANGED
package/types/bricks/QrCode.ts
CHANGED
package/types/bricks/Rect.ts
CHANGED
|
@@ -168,7 +168,7 @@ Default property:
|
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
/* Slideshow brick
|
|
171
|
+
/* Slideshow brick */
|
|
172
172
|
export type BrickSlideshow = Brick &
|
|
173
173
|
BrickSlideshowDef & {
|
|
174
174
|
templateKey: 'BRICK_SLIDESHOW'
|
package/types/bricks/Text.ts
CHANGED
|
@@ -209,7 +209,7 @@ Default property:
|
|
|
209
209
|
}
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
-
/* Text Input brick
|
|
212
|
+
/* Text Input brick */
|
|
213
213
|
export type BrickTextInput = Brick &
|
|
214
214
|
BrickTextInputDef & {
|
|
215
215
|
templateKey: 'BRICK_TEXT_INPUT'
|
package/types/bricks/Video.ts
CHANGED
package/types/bricks/WebView.ts
CHANGED
|
@@ -141,7 +141,7 @@ Default property:
|
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
/* WebView brick
|
|
144
|
+
/* WebView brick */
|
|
145
145
|
export type BrickWebView = Brick &
|
|
146
146
|
BrickWebViewDef & {
|
|
147
147
|
templateKey: 'BRICK_WEBVIEW'
|
package/types/canvas.ts
CHANGED
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
|
package/types/data-calc.ts
CHANGED
|
@@ -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 <think> 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
package/utils/event-props.ts
CHANGED
|
@@ -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
|