hoomanjs 1.42.0 → 1.43.0
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/README.md +3 -3
- package/dist/acp/acp-agent.js +21 -3
- package/dist/acp/acp-agent.js.map +1 -1
- package/dist/chat/app.js +19 -2
- package/dist/chat/app.js.map +1 -1
- package/dist/chat/components/BottomChrome.d.ts +1 -0
- package/dist/chat/components/BottomChrome.js.map +1 -1
- package/dist/chat/components/StatusBar.d.ts +1 -0
- package/dist/chat/components/StatusBar.js +3 -0
- package/dist/chat/components/StatusBar.js.map +1 -1
- package/dist/configure/app.js +153 -4
- package/dist/configure/app.js.map +1 -1
- package/dist/configure/types.d.ts +3 -0
- package/dist/core/config.d.ts +75 -5
- package/dist/core/config.js +43 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/models/hub-download.d.ts +27 -0
- package/dist/core/models/hub-download.js +136 -0
- package/dist/core/models/hub-download.js.map +1 -0
- package/dist/core/models/index.js +1 -0
- package/dist/core/models/index.js.map +1 -1
- package/dist/core/models/llama-cpp/index.js +6 -3
- package/dist/core/models/llama-cpp/index.js.map +1 -1
- package/dist/core/models/llama-cpp/resolve-model.js +3 -132
- package/dist/core/models/llama-cpp/resolve-model.js.map +1 -1
- package/dist/core/models/llama-cpp/strands-llama-cpp.d.ts +7 -1
- package/dist/core/models/llama-cpp/strands-llama-cpp.js +9 -3
- package/dist/core/models/llama-cpp/strands-llama-cpp.js.map +1 -1
- package/dist/core/models/mlx/index.d.ts +13 -0
- package/dist/core/models/mlx/index.js +47 -0
- package/dist/core/models/mlx/index.js.map +1 -0
- package/dist/core/models/mlx/resolve-model.d.ts +31 -0
- package/dist/core/models/mlx/resolve-model.js +149 -0
- package/dist/core/models/mlx/resolve-model.js.map +1 -0
- package/dist/core/models/mlx/strands-mlx.d.ts +45 -0
- package/dist/core/models/mlx/strands-mlx.js +439 -0
- package/dist/core/models/mlx/strands-mlx.js.map +1 -0
- package/dist/core/models/types.d.ts +168 -14
- package/dist/core/models/types.js +43 -3
- package/dist/core/models/types.js.map +1 -1
- package/dist/core/skills/built-in/hooman-config/SKILL.md +40 -5
- package/dist/core/skills/built-in/hooman-config/providers.md +4 -1
- package/dist/core/utils/billing.d.ts +29 -2
- package/dist/core/utils/billing.js +45 -4
- package/dist/core/utils/billing.js.map +1 -1
- package/dist/core/utils/reasoning-effort.d.ts +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { StrandsMlxModel } from "./strands-mlx.js";
|
|
2
|
+
import { REASONING_BUDGET_TOKENS } from "../types.js";
|
|
3
|
+
import { markTotalInclusiveInputUsage } from "../usage.js";
|
|
4
|
+
/**
|
|
5
|
+
* Strands {@link Model} backed by in-process Apple MLX via `mlex.js`
|
|
6
|
+
* (Apple Silicon Metal GPU; supported architectures: Qwen2/Llama-shaped,
|
|
7
|
+
* Qwen3, Qwen3.5 dense/MoE/vision, Gemma 4 text/multi-modal, NemotronH,
|
|
8
|
+
* DharaAR). Any quantization scheme MLX ships loads — bf16/fp16, affine
|
|
9
|
+
* 2–8 bit, mxfp4/mxfp8/nvfp4, and mixed per-layer checkpoints like OptiQ or
|
|
10
|
+
* Google QAT. MLX-format weights (e.g. `mlx-community` repos) are fetched
|
|
11
|
+
* from the Hugging Face Hub via `@huggingface/hub` into
|
|
12
|
+
* `~/.hooman/cache/huggingface` on first use.
|
|
13
|
+
*/
|
|
14
|
+
export function create(providerOptions, llmOptions) {
|
|
15
|
+
// Shared `reasoning` semantics: presence enables thinking (`effort`
|
|
16
|
+
// capping the reasoning span via mlex's reasoningBudgetTokens); omitting
|
|
17
|
+
// it renders the chat template with thinking off.
|
|
18
|
+
const reasoning = providerOptions.reasoning;
|
|
19
|
+
const effort = reasoning?.effort;
|
|
20
|
+
// `undefined`/`null`/`false` all disable caching; an object (even `{}`)
|
|
21
|
+
// enables it. Normalize `null` away since the internal model config only
|
|
22
|
+
// distinguishes `MlxPromptCacheConfig | false`.
|
|
23
|
+
const promptCache = providerOptions.promptCache;
|
|
24
|
+
const model = new StrandsMlxModel({
|
|
25
|
+
modelId: llmOptions.model,
|
|
26
|
+
...(providerOptions.hfToken ? { hfToken: providerOptions.hfToken } : {}),
|
|
27
|
+
...(promptCache !== undefined
|
|
28
|
+
? { promptCache: promptCache === null ? false : promptCache }
|
|
29
|
+
: {}),
|
|
30
|
+
...(reasoning !== undefined
|
|
31
|
+
? {
|
|
32
|
+
reasoning: { ...(effort !== undefined ? { effort } : {}) },
|
|
33
|
+
thoughtBudgetTokens: REASONING_BUDGET_TOKENS[effort ?? "medium"],
|
|
34
|
+
}
|
|
35
|
+
: {}),
|
|
36
|
+
...(llmOptions.temperature !== undefined
|
|
37
|
+
? { temperature: llmOptions.temperature }
|
|
38
|
+
: {}),
|
|
39
|
+
...(llmOptions.maxTokens !== undefined
|
|
40
|
+
? { maxTokens: llmOptions.maxTokens }
|
|
41
|
+
: {}),
|
|
42
|
+
});
|
|
43
|
+
// mlex usage is OpenAI-style: promptTokens includes cachedTokens.
|
|
44
|
+
markTotalInclusiveInputUsage(model);
|
|
45
|
+
return model;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/models/mlx/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAG3D;;;;;;;;;GASG;AACH,MAAM,UAAU,MAAM,CACpB,eAAmC,EACnC,UAAsB;IAEtB,oEAAoE;IACpE,yEAAyE;IACzE,kDAAkD;IAClD,MAAM,SAAS,GAAG,eAAe,CAAC,SAAS,CAAC;IAC5C,MAAM,MAAM,GAAG,SAAS,EAAE,MAAM,CAAC;IACjC,wEAAwE;IACxE,yEAAyE;IACzE,gDAAgD;IAChD,MAAM,WAAW,GAAG,eAAe,CAAC,WAAW,CAAC;IAChD,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC;QAChC,OAAO,EAAE,UAAU,CAAC,KAAK;QACzB,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,eAAe,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxE,GAAG,CAAC,WAAW,KAAK,SAAS;YAC3B,CAAC,CAAC,EAAE,WAAW,EAAE,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,EAAE;YAC7D,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,SAAS,KAAK,SAAS;YACzB,CAAC,CAAC;gBACE,SAAS,EAAE,EAAE,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;gBAC1D,mBAAmB,EAAE,uBAAuB,CAAC,MAAM,IAAI,QAAQ,CAAC;aACjE;YACH,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,UAAU,CAAC,WAAW,KAAK,SAAS;YACtC,CAAC,CAAC,EAAE,WAAW,EAAE,UAAU,CAAC,WAAW,EAAE;YACzC,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,UAAU,CAAC,SAAS,KAAK,SAAS;YACpC,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,SAAS,EAAE;YACrC,CAAC,CAAC,EAAE,CAAC;KACR,CAAC,CAAC;IACH,kEAAkE;IAClE,4BAA4B,CAAC,KAAK,CAAC,CAAC;IACpC,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MLX model repos are cached under `~/.hooman/cache/huggingface` (HF cache
|
|
3
|
+
* layout), shared with the llama-cpp provider's GGUF downloads.
|
|
4
|
+
*/
|
|
5
|
+
export declare const mlxCacheDir: () => string;
|
|
6
|
+
export type ParsedModelSpec = {
|
|
7
|
+
kind: "local";
|
|
8
|
+
path: string;
|
|
9
|
+
} | {
|
|
10
|
+
kind: "hub";
|
|
11
|
+
repo: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Parse an LLM `model` value into either a local MLX model directory or a
|
|
15
|
+
* Hugging Face repo designation. Accepted shapes (an optional `hf:` prefix is
|
|
16
|
+
* stripped):
|
|
17
|
+
* - `/abs/path/to/model-dir`, `./rel/model-dir`, `~/models/model-dir`
|
|
18
|
+
* (a directory containing `config.json` + safetensors weights)
|
|
19
|
+
* - `owner/repo` (an MLX-format repo, e.g. from `mlx-community`)
|
|
20
|
+
*/
|
|
21
|
+
export declare function parseModelSpec(model: string): ParsedModelSpec;
|
|
22
|
+
/**
|
|
23
|
+
* Resolve a model spec to a local MLX model directory, downloading the repo
|
|
24
|
+
* (config, safetensors weights, tokenizer files) from the Hugging Face Hub
|
|
25
|
+
* into the Hooman cache when needed. Weight shards are reported as shards of
|
|
26
|
+
* one download via `subscribeModelDownloadProgress`; the smaller JSON/
|
|
27
|
+
* tokenizer files download silently unless they exceed the reporter's
|
|
28
|
+
* blob-size threshold. Returns the snapshot directory containing
|
|
29
|
+
* `config.json`, which `mlex.js`'s `MlexModel.load` consumes directly.
|
|
30
|
+
*/
|
|
31
|
+
export declare function resolveModelDir(model: string, hfToken?: string): Promise<string>;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { existsSync } from "fs";
|
|
2
|
+
import { homedir } from "os";
|
|
3
|
+
import { dirname, join, sep } from "path";
|
|
4
|
+
import { listFiles, modelInfo } from "@huggingface/hub";
|
|
5
|
+
import { cachePath } from "../../utils/paths.js";
|
|
6
|
+
import { downloadFileWithProgress } from "../hub-download.js";
|
|
7
|
+
/**
|
|
8
|
+
* MLX model repos are cached under `~/.hooman/cache/huggingface` (HF cache
|
|
9
|
+
* layout), shared with the llama-cpp provider's GGUF downloads.
|
|
10
|
+
*/
|
|
11
|
+
export const mlxCacheDir = () => join(cachePath(), "huggingface");
|
|
12
|
+
function expandHome(p) {
|
|
13
|
+
if (p === "~" || p.startsWith(`~${sep}`) || p.startsWith("~/")) {
|
|
14
|
+
return join(homedir(), p.slice(1));
|
|
15
|
+
}
|
|
16
|
+
return p;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parse an LLM `model` value into either a local MLX model directory or a
|
|
20
|
+
* Hugging Face repo designation. Accepted shapes (an optional `hf:` prefix is
|
|
21
|
+
* stripped):
|
|
22
|
+
* - `/abs/path/to/model-dir`, `./rel/model-dir`, `~/models/model-dir`
|
|
23
|
+
* (a directory containing `config.json` + safetensors weights)
|
|
24
|
+
* - `owner/repo` (an MLX-format repo, e.g. from `mlx-community`)
|
|
25
|
+
*/
|
|
26
|
+
export function parseModelSpec(model) {
|
|
27
|
+
const spec = (model.startsWith("hf:") ? model.slice(3) : model).trim();
|
|
28
|
+
if (spec.length === 0) {
|
|
29
|
+
throw new Error("MLX model is not configured");
|
|
30
|
+
}
|
|
31
|
+
const expanded = expandHome(spec);
|
|
32
|
+
const looksLikePath = spec.startsWith("/") ||
|
|
33
|
+
spec.startsWith("./") ||
|
|
34
|
+
spec.startsWith("../") ||
|
|
35
|
+
spec.startsWith("~");
|
|
36
|
+
if (looksLikePath || existsSync(join(expanded, "config.json"))) {
|
|
37
|
+
return { kind: "local", path: expanded };
|
|
38
|
+
}
|
|
39
|
+
const segments = spec.split("/").filter((s) => s.length > 0);
|
|
40
|
+
if (segments.length === 2) {
|
|
41
|
+
return { kind: "hub", repo: spec };
|
|
42
|
+
}
|
|
43
|
+
throw new Error(`Invalid MLX model "${model}". Use a local MLX model directory ` +
|
|
44
|
+
`or an "owner/repo" Hugging Face repo (MLX format, e.g. mlx-community/...).`);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Repo files the MLX runtime needs: model config + weights + tokenizer
|
|
48
|
+
* assets. Everything else (README, images, .gitattributes) is skipped.
|
|
49
|
+
*/
|
|
50
|
+
const MODEL_FILE_EXTENSIONS = [
|
|
51
|
+
".safetensors",
|
|
52
|
+
".json",
|
|
53
|
+
".jinja",
|
|
54
|
+
".txt",
|
|
55
|
+
".model",
|
|
56
|
+
];
|
|
57
|
+
function isModelFile(path) {
|
|
58
|
+
const lower = path.toLowerCase();
|
|
59
|
+
if (lower === ".gitattributes") {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
return MODEL_FILE_EXTENSIONS.some((ext) => lower.endsWith(ext));
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Resolve a model spec to a local MLX model directory, downloading the repo
|
|
66
|
+
* (config, safetensors weights, tokenizer files) from the Hugging Face Hub
|
|
67
|
+
* into the Hooman cache when needed. Weight shards are reported as shards of
|
|
68
|
+
* one download via `subscribeModelDownloadProgress`; the smaller JSON/
|
|
69
|
+
* tokenizer files download silently unless they exceed the reporter's
|
|
70
|
+
* blob-size threshold. Returns the snapshot directory containing
|
|
71
|
+
* `config.json`, which `mlex.js`'s `MlexModel.load` consumes directly.
|
|
72
|
+
*/
|
|
73
|
+
export async function resolveModelDir(model, hfToken) {
|
|
74
|
+
const parsed = parseModelSpec(model);
|
|
75
|
+
if (parsed.kind === "local") {
|
|
76
|
+
if (!existsSync(join(parsed.path, "config.json"))) {
|
|
77
|
+
throw new Error(`MLX model directory not found (no config.json): ${parsed.path}`);
|
|
78
|
+
}
|
|
79
|
+
return parsed.path;
|
|
80
|
+
}
|
|
81
|
+
const accessToken = hfToken?.trim() || process.env.HF_TOKEN?.trim();
|
|
82
|
+
const credentials = accessToken ? { accessToken } : {};
|
|
83
|
+
const cacheDir = mlxCacheDir();
|
|
84
|
+
// Pin every file to the repo's current head commit: the HF cache layout
|
|
85
|
+
// names snapshot dirs after the revision each file resolved to, so
|
|
86
|
+
// un-pinned multi-file downloads would scatter across snapshot dirs and
|
|
87
|
+
// never form one complete model directory.
|
|
88
|
+
const info = await modelInfo({
|
|
89
|
+
name: parsed.repo,
|
|
90
|
+
additionalFields: ["sha"],
|
|
91
|
+
...(accessToken ? { accessToken } : {}),
|
|
92
|
+
});
|
|
93
|
+
const revision = info.sha;
|
|
94
|
+
if (typeof revision !== "string" || revision.length === 0) {
|
|
95
|
+
throw new Error(`Cannot resolve the current revision of Hugging Face repo "${parsed.repo}".`);
|
|
96
|
+
}
|
|
97
|
+
const files = [];
|
|
98
|
+
for await (const entry of listFiles({
|
|
99
|
+
repo: parsed.repo,
|
|
100
|
+
recursive: true,
|
|
101
|
+
revision,
|
|
102
|
+
...(accessToken ? { accessToken } : {}),
|
|
103
|
+
})) {
|
|
104
|
+
if (entry.type === "file" && isModelFile(entry.path)) {
|
|
105
|
+
files.push(entry.path);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (!files.includes("config.json")) {
|
|
109
|
+
throw new Error(`Hugging Face repo "${parsed.repo}" does not look like an MLX model ` +
|
|
110
|
+
`(no config.json). Use an MLX-format repo, e.g. from mlx-community.`);
|
|
111
|
+
}
|
|
112
|
+
const weights = files.filter((f) => f.toLowerCase().endsWith(".safetensors"));
|
|
113
|
+
if (weights.length === 0) {
|
|
114
|
+
throw new Error(`No .safetensors weights found in Hugging Face repo "${parsed.repo}".`);
|
|
115
|
+
}
|
|
116
|
+
// Small metadata files first (cheap, near-instant), then the weight shards
|
|
117
|
+
// with shard-indexed progress so the UI shows "shard i of n".
|
|
118
|
+
const metadata = files.filter((f) => !f.toLowerCase().endsWith(".safetensors"));
|
|
119
|
+
let configPath;
|
|
120
|
+
for (const filePath of metadata.sort()) {
|
|
121
|
+
const local = await downloadFileWithProgress({
|
|
122
|
+
repo: parsed.repo,
|
|
123
|
+
filePath,
|
|
124
|
+
cacheDir,
|
|
125
|
+
credentials,
|
|
126
|
+
model,
|
|
127
|
+
revision,
|
|
128
|
+
});
|
|
129
|
+
if (filePath === "config.json") {
|
|
130
|
+
configPath = local;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
weights.sort();
|
|
134
|
+
for (let i = 0; i < weights.length; i++) {
|
|
135
|
+
await downloadFileWithProgress({
|
|
136
|
+
repo: parsed.repo,
|
|
137
|
+
filePath: weights[i],
|
|
138
|
+
cacheDir,
|
|
139
|
+
credentials,
|
|
140
|
+
model,
|
|
141
|
+
revision,
|
|
142
|
+
...(weights.length > 1
|
|
143
|
+
? { shard: { index: i + 1, total: weights.length } }
|
|
144
|
+
: {}),
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
return dirname(configPath);
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=resolve-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-model.js","sourceRoot":"","sources":["../../../../src/core/models/mlx/resolve-model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAE9D;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,aAAa,CAAC,CAAC;AAKlE,SAAS,UAAU,CAAC,CAAS;IAC3B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/D,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IACvE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IACD,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,aAAa,GACjB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QACpB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QACrB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACvB,IAAI,aAAa,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC;QAC/D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC3C,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACrC,CAAC;IACD,MAAM,IAAI,KAAK,CACb,sBAAsB,KAAK,qCAAqC;QAC9D,4EAA4E,CAC/E,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,qBAAqB,GAAG;IAC5B,cAAc;IACd,OAAO;IACP,QAAQ;IACR,MAAM;IACN,QAAQ;CACT,CAAC;AAEF,SAAS,WAAW,CAAC,IAAY;IAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,IAAI,KAAK,KAAK,gBAAgB,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,qBAAqB,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AAClE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAa,EACb,OAAgB;IAEhB,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CACb,mDAAmD,MAAM,CAAC,IAAI,EAAE,CACjE,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IACD,MAAM,WAAW,GAAG,OAAO,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;IACpE,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAE/B,wEAAwE;IACxE,mEAAmE;IACnE,wEAAwE;IACxE,2CAA2C;IAC3C,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC;QAC3B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,gBAAgB,EAAE,CAAC,KAAK,CAAC;QACzB,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxC,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC;IAC1B,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CACb,6DAA6D,MAAM,CAAC,IAAI,IAAI,CAC7E,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,SAAS,CAAC;QAClC,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,SAAS,EAAE,IAAI;QACf,QAAQ;QACR,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxC,CAAC,EAAE,CAAC;QACH,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACrD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,sBAAsB,MAAM,CAAC,IAAI,oCAAoC;YACnE,oEAAoE,CACvE,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC;IAC9E,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,uDAAuD,MAAM,CAAC,IAAI,IAAI,CACvE,CAAC;IACJ,CAAC;IAED,2EAA2E;IAC3E,8DAA8D;IAC9D,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAC3B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,CACjD,CAAC;IACF,IAAI,UAA8B,CAAC;IACnC,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,MAAM,wBAAwB,CAAC;YAC3C,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,QAAQ;YACR,QAAQ;YACR,WAAW;YACX,KAAK;YACL,QAAQ;SACT,CAAC,CAAC;QACH,IAAI,QAAQ,KAAK,aAAa,EAAE,CAAC;YAC/B,UAAU,GAAG,KAAK,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,CAAC,IAAI,EAAE,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,wBAAwB,CAAC;YAC7B,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAE;YACrB,QAAQ;YACR,WAAW;YACX,KAAK;YACL,QAAQ;YACR,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;gBACpB,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE;gBACpD,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC,UAAW,CAAC,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Model } from "@strands-agents/sdk";
|
|
2
|
+
import type { BaseModelConfig, Message, StreamOptions } from "@strands-agents/sdk";
|
|
3
|
+
import type { ModelStreamEvent } from "@strands-agents/sdk";
|
|
4
|
+
import type { MlxPromptCacheConfig } from "../types.js";
|
|
5
|
+
export interface MlxModelConfig extends BaseModelConfig {
|
|
6
|
+
/**
|
|
7
|
+
* Model spec: `owner/repo` Hugging Face repo in MLX format (e.g.
|
|
8
|
+
* `mlx-community/...`) or a local MLX model directory containing
|
|
9
|
+
* `config.json` + safetensors weights.
|
|
10
|
+
*/
|
|
11
|
+
modelId?: string;
|
|
12
|
+
/** Hugging Face access token for gated/private repos (falls back to `HF_TOKEN`). */
|
|
13
|
+
hfToken?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Whether turns may reuse KV state from mlex's internal prompt-cache pool
|
|
16
|
+
* (prefix matching against previous calls), applied once when the model
|
|
17
|
+
* is loaded. `undefined`/`false` disables caching entirely (every
|
|
18
|
+
* generate call forwards `promptCache: false`); an object (even `{}`)
|
|
19
|
+
* enables it, with its fields overriding mlex's own pool-sizing defaults.
|
|
20
|
+
*/
|
|
21
|
+
promptCache?: MlxPromptCacheConfig | false;
|
|
22
|
+
/**
|
|
23
|
+
* Thinking controls. Presence enables reasoning (`enableThinking: true` on
|
|
24
|
+
* the chat template) with `effort` capping the reasoning span via
|
|
25
|
+
* `reasoningBudgetTokens`. Absence disables it: the template renders with
|
|
26
|
+
* thinking off and reasoning content is dropped.
|
|
27
|
+
*/
|
|
28
|
+
reasoning?: {
|
|
29
|
+
effort?: "minimal" | "low" | "medium" | "high";
|
|
30
|
+
};
|
|
31
|
+
/** Cap on reasoning-span tokens while thinking is enabled. */
|
|
32
|
+
thoughtBudgetTokens?: number;
|
|
33
|
+
}
|
|
34
|
+
/** Strands {@link Model} backed by in-process Apple MLX via `mlex.js`. */
|
|
35
|
+
export declare class StrandsMlxModel extends Model<MlxModelConfig> {
|
|
36
|
+
private config;
|
|
37
|
+
private modelPromise;
|
|
38
|
+
constructor(config: MlxModelConfig);
|
|
39
|
+
updateConfig(modelConfig: MlxModelConfig): void;
|
|
40
|
+
getConfig(): MlxModelConfig;
|
|
41
|
+
private getModel;
|
|
42
|
+
private initModel;
|
|
43
|
+
private buildGenerateOptions;
|
|
44
|
+
stream(messages: Message[], options?: StreamOptions): AsyncIterable<ModelStreamEvent>;
|
|
45
|
+
}
|