@mlx-node/agent 0.0.8 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/catalog.d.ts +15 -0
  2. package/dist/catalog.d.ts.map +1 -1
  3. package/dist/catalog.js +15 -0
  4. package/dist/cold-tier.d.ts +99 -0
  5. package/dist/cold-tier.d.ts.map +1 -0
  6. package/dist/cold-tier.js +155 -0
  7. package/dist/extensions/local-image-input.d.ts +24 -0
  8. package/dist/extensions/local-image-input.d.ts.map +1 -0
  9. package/dist/extensions/local-image-input.js +114 -0
  10. package/dist/extensions/subagent.d.ts +20 -1
  11. package/dist/extensions/subagent.d.ts.map +1 -1
  12. package/dist/extensions/subagent.js +46 -6
  13. package/dist/paths.d.ts +13 -0
  14. package/dist/paths.d.ts.map +1 -0
  15. package/dist/paths.js +18 -0
  16. package/dist/provider/events.d.ts +9 -0
  17. package/dist/provider/events.d.ts.map +1 -1
  18. package/dist/provider/events.js +15 -0
  19. package/dist/provider/index.d.ts +12 -1
  20. package/dist/provider/index.d.ts.map +1 -1
  21. package/dist/provider/index.js +153 -7
  22. package/dist/provider/metrics-trace.d.ts +274 -0
  23. package/dist/provider/metrics-trace.d.ts.map +1 -0
  24. package/dist/provider/metrics-trace.js +174 -0
  25. package/dist/provider/mlx-identity.d.ts +16 -0
  26. package/dist/provider/mlx-identity.d.ts.map +1 -0
  27. package/dist/provider/mlx-identity.js +15 -0
  28. package/dist/provider/model-host.d.ts +45 -3
  29. package/dist/provider/model-host.d.ts.map +1 -1
  30. package/dist/provider/model-host.js +34 -2
  31. package/dist/provider/model-registry-filter.d.ts +74 -18
  32. package/dist/provider/model-registry-filter.d.ts.map +1 -1
  33. package/dist/provider/model-registry-filter.js +229 -38
  34. package/dist/provider/models.d.ts +2 -3
  35. package/dist/provider/models.d.ts.map +1 -1
  36. package/dist/provider/models.js +46 -20
  37. package/dist/provider/stream-adapter.d.ts +37 -4
  38. package/dist/provider/stream-adapter.d.ts.map +1 -1
  39. package/dist/provider/stream-adapter.js +58 -3
  40. package/dist/provider/warm-reuse.d.ts +11 -8
  41. package/dist/provider/warm-reuse.d.ts.map +1 -1
  42. package/dist/provider/warm-reuse.js +14 -7
  43. package/dist/run-agent.d.ts +12 -3
  44. package/dist/run-agent.d.ts.map +1 -1
  45. package/dist/run-agent.js +31 -5
  46. package/package.json +10 -5
@@ -18,18 +18,19 @@
18
18
  * the reused prefix and skip the corresponding re-prefill.
19
19
  *
20
20
  * Fields accessed: `inFlight`, `history`, `lastImagesKey`, `lastAudioKey`, `turnCount`,
21
- * `unresolvedOkToolCallCount`, `needsFullReplay`. These are TypeScript `private` fields on
22
- * `ChatSession` (compile-time only) — at runtime they are ordinary
23
- * properties. The cast through {@link ChatSessionWarmReuseInternals}
24
- * gives this helper a typed view of the instance without relaxing the
25
- * class's `private` declarations. The field names MUST stay in sync
26
- * with `packages/lm/src/chat-session.ts`; a mismatch would silently
27
- * skip the intended state wipe — the drift test in
21
+ * `unresolvedOkToolCallCount`, `needsFullReplay`, `defaultConfig`, `activeTools`.
22
+ * These are TypeScript `private` fields on `ChatSession` (compile-time
23
+ * only) — at runtime they are ordinary properties. The cast through
24
+ * {@link ChatSessionWarmReuseInternals} gives this helper a typed view
25
+ * of the instance without relaxing the class's `private` declarations.
26
+ * The field names MUST stay in sync with
27
+ * `packages/lm/src/chat-session.ts`; a mismatch would silently skip
28
+ * the intended state wipe — the drift test in
28
29
  * `packages/agent/__test__/warm-reuse.test.ts` checks every name in
29
30
  * {@link WARM_REUSE_TOUCHED_FIELDS} against a real `ChatSession`
30
31
  * instance.
31
32
  */
32
- import type { ChatSession, SessionCapableModel } from '@mlx-node/lm';
33
+ import type { ChatConfig, ChatSession, SessionCapableModel } from '@mlx-node/lm';
33
34
  /**
34
35
  * Private structural view of the `ChatSession` JS-side state that the
35
36
  * warm-reuse helper needs to wipe. Mirrors the internal state
@@ -45,6 +46,8 @@ interface ChatSessionWarmReuseInternals {
45
46
  turnCount: number;
46
47
  unresolvedOkToolCallCount: number | null;
47
48
  needsFullReplay: boolean;
49
+ defaultConfig?: ChatConfig;
50
+ activeTools: ChatConfig['tools'];
48
51
  }
49
52
  /**
50
53
  * Runtime list of the `ChatSession` private field names this module
@@ -1 +1 @@
1
- {"version":3,"file":"warm-reuse.d.ts","sourceRoot":"","sources":["../../src/provider/warm-reuse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAErE;;;;;;GAMG;AACH,UAAU,6BAA6B;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,yBAAyB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,eAAe,EAAE,OAAO,CAAC;CAC1B;AAkBD;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAgD,aAAa,CACjG,MAAM,6BAA6B,CACpC,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,sCAAsC,CAAC,CAAC,SAAS,mBAAmB,EACxF,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,GACtB,OAAO,CAAC,IAAI,CAAC,CAqBf"}
1
+ {"version":3,"file":"warm-reuse.d.ts","sourceRoot":"","sources":["../../src/provider/warm-reuse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEjF;;;;;;GAMG;AACH,UAAU,6BAA6B;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,yBAAyB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,UAAU,CAAC;IAC3B,WAAW,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;CAClC;AAoBD;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAgD,aAAa,CACjG,MAAM,6BAA6B,CACpC,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,sCAAsC,CAAC,CAAC,SAAS,mBAAmB,EACxF,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,GACtB,OAAO,CAAC,IAAI,CAAC,CAyBf"}
@@ -18,13 +18,14 @@
18
18
  * the reused prefix and skip the corresponding re-prefill.
19
19
  *
20
20
  * Fields accessed: `inFlight`, `history`, `lastImagesKey`, `lastAudioKey`, `turnCount`,
21
- * `unresolvedOkToolCallCount`, `needsFullReplay`. These are TypeScript `private` fields on
22
- * `ChatSession` (compile-time only) — at runtime they are ordinary
23
- * properties. The cast through {@link ChatSessionWarmReuseInternals}
24
- * gives this helper a typed view of the instance without relaxing the
25
- * class's `private` declarations. The field names MUST stay in sync
26
- * with `packages/lm/src/chat-session.ts`; a mismatch would silently
27
- * skip the intended state wipe — the drift test in
21
+ * `unresolvedOkToolCallCount`, `needsFullReplay`, `defaultConfig`, `activeTools`.
22
+ * These are TypeScript `private` fields on `ChatSession` (compile-time
23
+ * only) — at runtime they are ordinary properties. The cast through
24
+ * {@link ChatSessionWarmReuseInternals} gives this helper a typed view
25
+ * of the instance without relaxing the class's `private` declarations.
26
+ * The field names MUST stay in sync with
27
+ * `packages/lm/src/chat-session.ts`; a mismatch would silently skip
28
+ * the intended state wipe — the drift test in
28
29
  * `packages/agent/__test__/warm-reuse.test.ts` checks every name in
29
30
  * {@link WARM_REUSE_TOUCHED_FIELDS} against a real `ChatSession`
30
31
  * instance.
@@ -43,6 +44,8 @@ const WARM_REUSE_TOUCHED_FIELD_SET = {
43
44
  turnCount: true,
44
45
  unresolvedOkToolCallCount: true,
45
46
  needsFullReplay: true,
47
+ defaultConfig: true,
48
+ activeTools: true,
46
49
  };
47
50
  /**
48
51
  * Runtime list of the `ChatSession` private field names this module
@@ -85,4 +88,8 @@ export async function resetPreservingNativeCacheForWarmReuse(session) {
85
88
  internals.turnCount = 0;
86
89
  internals.unresolvedOkToolCallCount = null;
87
90
  internals.needsFullReplay = false;
91
+ // Tools are conversation state. A provider replay can switch to an
92
+ // unrelated history, so restore constructor defaults exactly like
93
+ // ChatSession.reset() instead of leaking the prior committed overlay.
94
+ internals.activeTools = internals.defaultConfig?.tools;
88
95
  }
@@ -17,7 +17,7 @@
17
17
  * critical on pi's hard `process.exit()` paths.
18
18
  */
19
19
  import type { InlineExtension } from '@earendil-works/pi-coding-agent';
20
- import { type FilterableModelRegistryConstructor } from './provider/model-registry-filter.js';
20
+ import { type FilterableModelRuntimeConstructor } from './provider/model-registry-filter.js';
21
21
  import type { MlxModelInfo } from './provider/models.js';
22
22
  /** Shape of pi's `main(argv, { extensionFactories })` — also the test seam. */
23
23
  export type RunAgentMain = (args: string[], opts: {
@@ -25,11 +25,11 @@ export type RunAgentMain = (args: string[], opts: {
25
25
  }) => Promise<void>;
26
26
  export interface RunAgentPi {
27
27
  main: RunAgentMain;
28
- ModelRegistry: FilterableModelRegistryConstructor;
28
+ ModelRuntime: FilterableModelRuntimeConstructor;
29
29
  }
30
30
  /** @internal Narrow lifecycle seam for the agent's paged config overlays. */
31
31
  export interface AgentPagedConfigOverrides {
32
- resolve(modelPath: string, modelType?: string): Promise<string>;
32
+ resolve(modelPath: string, modelType?: string, persistPagedCache?: boolean): Promise<string>;
33
33
  cleanup(): Promise<void>;
34
34
  }
35
35
  export interface RunAgentOptions {
@@ -41,6 +41,15 @@ export interface RunAgentOptions {
41
41
  argv: string[];
42
42
  /** Native inference-log path to surface after Pi takes over the TUI. */
43
43
  traceLogFile?: string;
44
+ /**
45
+ * Enable the SSD cold tier by default (the agent's default; the CLI sets it
46
+ * false for `--no-persist-cache`). Forwarded to {@link MlxModelHost}, which
47
+ * applies this ONE value to every load whose family is in
48
+ * `COLD_TIER_RESTORE_FAMILIES` — not to qwen3 alone. Families off that list
49
+ * are handed no policy because they can never persist, not because this flag
50
+ * spares them. `undefined` keeps the host's on-by-default behavior.
51
+ */
52
+ persistPagedCache?: boolean;
44
53
  /** @internal Test seam; when set, the pi dynamic import is skipped entirely. */
45
54
  piImpl?: RunAgentPi;
46
55
  /** @internal Test seam for paged model-path resolution and cleanup. */
@@ -1 +1 @@
1
- {"version":3,"file":"run-agent.d.ts","sourceRoot":"","sources":["../src/run-agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AASvE,OAAO,EACL,KAAK,kCAAkC,EAExC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,+EAA+E;AAC/E,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE;IAAE,kBAAkB,EAAE,eAAe,EAAE,CAAA;CAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE9G,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,YAAY,CAAC;IACnB,aAAa,EAAE,kCAAkC,CAAC;CACnD;AAED,6EAA6E;AAC7E,MAAM,WAAW,yBAAyB;IACxC,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,2FAA2F;IAC3F,SAAS,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,yDAAyD;IACzD,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gFAAgF;IAChF,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,uEAAuE;IACvE,oBAAoB,CAAC,EAAE,yBAAyB,CAAC;CAClD;AAED,mFAAmF;AACnF,wBAAgB,sBAAsB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAEpF;AAED;;;;;;;;;GASG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAmDnE"}
1
+ {"version":3,"file":"run-agent.d.ts","sourceRoot":"","sources":["../src/run-agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAWvE,OAAO,EACL,KAAK,iCAAiC,EAEvC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,+EAA+E;AAC/E,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE;IAAE,kBAAkB,EAAE,eAAe,EAAE,CAAA;CAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE9G,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,YAAY,CAAC;IACnB,YAAY,EAAE,iCAAiC,CAAC;CACjD;AAED,6EAA6E;AAC7E,MAAM,WAAW,yBAAyB;IACxC,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7F,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,2FAA2F;IAC3F,SAAS,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,yDAAyD;IACzD,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gFAAgF;IAChF,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,uEAAuE;IACvE,oBAAoB,CAAC,EAAE,yBAAyB,CAAC;CAClD;AAED,mFAAmF;AACnF,wBAAgB,sBAAsB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAEpF;AAED;;;;;;;;;GASG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA2EnE"}
package/dist/run-agent.js CHANGED
@@ -18,7 +18,9 @@
18
18
  */
19
19
  import { homedir } from 'node:os';
20
20
  import { join } from 'node:path';
21
+ import { coldCacheDrain } from '@mlx-node/core';
21
22
  import { PagedConfigOverrideManager } from '@mlx-node/lm';
23
+ import { createLocalImageInputExtension } from './extensions/local-image-input.js';
22
24
  import { createPermissionGateExtension } from './extensions/permission-gate.js';
23
25
  import { createSubagentExtension } from './extensions/subagent.js';
24
26
  import { createTerminalTitleExtension } from './extensions/terminal-title.js';
@@ -46,6 +48,15 @@ export async function runAgent(opts) {
46
48
  // Mirrors `mlx launch claude`: chunked paged prefill keeps long-prompt
47
49
  // TTFT bounded on the default paged path.
48
50
  process.env.MLX_PAGED_PREFILL_CHUNK_SIZE ??= '2048';
51
+ // Hard offline invariant — NOT a user-overridable default, hence `=` not `??=`.
52
+ // `mlx agent` is local-only: no cloud provider may ever be contacted. pi 0.81.1's
53
+ // interactive and RPC startup call `ModelRuntime.refresh()`, which when PI_OFFLINE
54
+ // is unset fetches remote provider catalogs from pi.dev and can refresh a persisted
55
+ // cloud credential — a network path the mlx-only prototype filter does NOT cover
56
+ // (it patches the read methods, not `refresh`). Forcing PI_OFFLINE=1 here, before pi
57
+ // is imported below, also pins every ModelRuntime in this process to `allowNetwork`
58
+ // off, so no ambient/prior cloud credential can leak outbound traffic.
59
+ process.env.PI_OFFLINE = '1';
49
60
  // Force every paged-capable agent family through an isolated config clone.
50
61
  // This includes quantized LFM2 (whose standalone default is deliberately
51
62
  // flat) and Qwen3.5 dense/MoE (whose text-only defaults are flat). Gemma4's
@@ -55,19 +66,23 @@ export async function runAgent(opts) {
55
66
  const preserveEmbeddedGemmaDraft = agentGemmaDraftEnabled();
56
67
  const pagedConfigOverrides = opts.pagedConfigOverrides ?? new PagedConfigOverrideManager({ preserveEmbeddedGemmaDraft });
57
68
  const modelHost = new MlxModelHost(opts.models.map((model) => model.discovered), {
58
- resolveModelPathFn: (model) => pagedConfigOverrides.resolve(model.path, model.modelType),
69
+ resolveModelPathFn: (model, policy) => pagedConfigOverrides.resolve(model.path, model.modelType, policy?.persistPagedCache),
59
70
  requirePagedCache: true,
71
+ persistPagedCache: opts.persistPagedCache,
60
72
  });
61
- // Keep the pi import strictly behind the seam. The seam carries BOTH main
62
- // and its registry class, so tests and production exercise the same policy
63
- // installation/lifecycle instead of being able to bypass it accidentally.
73
+ // Keep the pi import strictly behind the seam. The seam carries BOTH main and
74
+ // the ModelRuntime class, so tests and production exercise the same policy
75
+ // installation/lifecycle instead of being able to bypass it accidentally. The
76
+ // filter patches the runtime prototype (not the extension-only ModelRegistry
77
+ // facade), which is where the selector / listing / resolution paths read.
64
78
  const pi = opts.piImpl ?? (await import('@earendil-works/pi-coding-agent'));
65
- const restoreModelRegistry = installMlxOnlyModelRegistryFilter(pi.ModelRegistry, opts.models.map((model) => model.discovered.name));
79
+ const restoreModelRegistry = installMlxOnlyModelRegistryFilter(pi.ModelRuntime, opts.models.map((model) => model.discovered.name));
66
80
  const subagentsEnabled = opts.models.length > 0 && !opts.argv.includes('--no-extensions') && !opts.argv.includes('-ne');
67
81
  try {
68
82
  await pi.main(opts.argv, {
69
83
  extensionFactories: [
70
84
  createMlxProviderExtension(opts.models, modelHost),
85
+ createLocalImageInputExtension(),
71
86
  createPermissionGateExtension(),
72
87
  ...(subagentsEnabled ? [createSubagentExtension()] : []),
73
88
  ...(opts.traceLogFile !== undefined ? [createTraceNoticeExtension(opts.traceLogFile)] : []),
@@ -81,6 +96,17 @@ export async function runAgent(opts) {
81
96
  }
82
97
  finally {
83
98
  await pagedConfigOverrides.cleanup();
99
+ // `mlx agent -p` is one-shot: flush any accepted cold-tier prefix blocks
100
+ // to disk before the process exits, otherwise a prompt's just-persisted
101
+ // KV could still be queued/mid-write when we return. No-op when the tier
102
+ // was never opened, bounded so a stuck fsync can't hang exit, and never
103
+ // allowed to throw out of cleanup (best-effort durability).
104
+ try {
105
+ coldCacheDrain(5000);
106
+ }
107
+ catch {
108
+ // Best-effort: a drain failure must never mask the real exit path.
109
+ }
84
110
  }
85
111
  }
86
112
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mlx-node/agent",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "homepage": "https://github.com/mlx-node/mlx-node",
5
5
  "bugs": {
6
6
  "url": "https://github.com/mlx-node/mlx-node/issues"
@@ -21,16 +21,21 @@
21
21
  ".": {
22
22
  "types": "./dist/index.d.ts",
23
23
  "import": "./dist/index.js"
24
+ },
25
+ "./catalog": {
26
+ "types": "./dist/catalog.d.ts",
27
+ "default": "./dist/catalog.js"
24
28
  }
25
29
  },
26
30
  "scripts": {
27
31
  "build": "tsc -b"
28
32
  },
29
33
  "dependencies": {
30
- "@earendil-works/pi-ai": "0.80.6",
31
- "@earendil-works/pi-coding-agent": "0.80.6",
32
- "@mlx-node/lm": "0.0.8",
33
- "@mlx-node/server": "0.0.8",
34
+ "@earendil-works/pi-ai": "0.81.1",
35
+ "@earendil-works/pi-coding-agent": "0.81.1",
36
+ "@mlx-node/core": "0.0.9",
37
+ "@mlx-node/lm": "0.0.9",
38
+ "@mlx-node/server": "0.0.9",
34
39
  "typebox": "1.3.6"
35
40
  },
36
41
  "devDependencies": {