mlx-bun 0.0.5 → 0.0.6
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 +11 -2
- package/docs/dag/training-inference-map.html +575 -0
- package/docs/design/memory-system.md +193 -295
- package/docs/design/orpo-dynamic-lambda.md +179 -0
- package/docs/design/orpo-future-enhancements.md +42 -0
- package/docs/design/orpo-training.md +13 -0
- package/docs/design/parity-tier-dag.md +143 -0
- package/docs/design/w4a16-compute-precision-spike.md +232 -0
- package/docs/investigations/orpo-base-uf-experiment-and-directions.md +120 -0
- package/docs/investigations/orpo-flash-cce-pin-leak.md +167 -0
- package/docs/investigations/orpo-uf-testing-handoff.md +126 -0
- package/docs/investigations/steel-flash-cce-handoff.md +58 -0
- package/docs/investigations/trainer-validation-experiment.md +173 -0
- package/docs/reference/memory.md +77 -0
- package/docs/reference/orpo-quickstart.md +44 -5
- package/docs/reference/training.md +9 -5
- package/package.json +1 -1
- package/src/cli.ts +651 -18
- package/src/eval/runner.ts +76 -6
- package/src/eval/tasks/bfcl.ts +49 -15
- package/src/eval/tasks/gsm8k.ts +21 -9
- package/src/eval/tasks/hashhop.ts +33 -4
- package/src/eval/tasks/humaneval.ts +30 -8
- package/src/eval/tasks/ifeval.ts +52 -18
- package/src/eval/tasks/mmlu.ts +85 -74
- package/src/jobs/runner.ts +6 -0
- package/src/memory/chunk.ts +25 -0
- package/src/memory/cluster.ts +24 -0
- package/src/memory/db.ts +114 -0
- package/src/memory/ingest.ts +22 -0
- package/src/memory/pipeline.ts +63 -0
- package/src/memory/prompts.ts +23 -0
- package/src/memory/schedule.ts +163 -0
- package/src/memory/synthesize.ts +29 -0
- package/src/memory/tools.ts +399 -0
- package/src/memory/vault.ts +694 -0
- package/src/memory/wikify.ts +23 -0
- package/src/mlx/metal-kernel.ts +13 -0
- package/src/model/flash-attention.ts +5 -3
- package/src/pi-provider.ts +29 -13
- package/src/pi-session.ts +81 -0
- package/src/pi-terminal.ts +13 -24
- package/src/pi-web.ts +246 -166
- package/src/quantize/job.ts +17 -2
- package/src/quantize/quantizer.ts +26 -2
- package/src/server.ts +213 -44
- package/src/tokenizer.ts +6 -2
- package/src/train/dataset.ts +11 -3
- package/src/train/flash-cce.ts +18 -5
- package/src/train/job.ts +41 -4
- package/src/train/loss.ts +10 -4
- package/src/train/trainer.ts +62 -3
- package/src/train/watch.ts +542 -0
- package/src/web/app.html +264 -14
- package/src/web/skills/memory/SKILL.md +97 -0
- package/src/web/skills/web-research/SKILL.md +3 -1
- package/src/web/skills.ts +46 -8
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// mlx-bun memory — synthesis stage 5: WIKIFY (deterministic). ⚠️ M1 STUB.
|
|
2
|
+
//
|
|
3
|
+
// Non-model editorial cleanup after synthesis: canonicalize [[wikilinks]]
|
|
4
|
+
// (spaces↔underscores, case, resolve to existing stems), repair footnotes, and
|
|
5
|
+
// run the deterministic editorial gate. Non-fatal — a failure here logs and
|
|
6
|
+
// continues; it never corrupts an article. Mirrors lucien's wikify.ts +
|
|
7
|
+
// normalize-wikilinks.ts + normalize-footnotes.ts.
|
|
8
|
+
//
|
|
9
|
+
// See docs/design/memory-system.md → "The nightly pipeline" (wikify/normalize).
|
|
10
|
+
|
|
11
|
+
import type { SynthesisEvent } from "./pipeline";
|
|
12
|
+
|
|
13
|
+
export interface WikifyResult {
|
|
14
|
+
articlesNormalized: number;
|
|
15
|
+
linksFixed: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Deterministic editorial gate + link/footnote normalize. STUB. */
|
|
19
|
+
export async function wikify(_onEvent?: (e: SynthesisEvent) => void): Promise<WikifyResult> {
|
|
20
|
+
// TODO(M1): resolveWikilinkToStem across touched articles (vault.ts already
|
|
21
|
+
// has the resolver), footnote renumber/repair, {{stub}} marking.
|
|
22
|
+
throw new Error("memory.wikify is not implemented yet (M1)");
|
|
23
|
+
}
|
package/src/mlx/metal-kernel.ts
CHANGED
|
@@ -67,6 +67,11 @@ export class MetalKernel {
|
|
|
67
67
|
apply(inputs: MlxArray[], call: MetalKernelCall): MlxArray[] {
|
|
68
68
|
if (this.#disposed) throw new Error("MetalKernel used after dispose");
|
|
69
69
|
const cfg = C.mlx_fast_metal_kernel_config_new();
|
|
70
|
+
// bun:ffi ptr() does NOT retain its argument, so any JS buffer whose pointer
|
|
71
|
+
// crosses an FFI call below is anchored here until that call returns —
|
|
72
|
+
// otherwise GC could free it mid-call (the lifetime class behind the
|
|
73
|
+
// flash-CCE pin bug). Pure-additive: holds references, changes no logic.
|
|
74
|
+
const keepAlive: unknown[] = [];
|
|
70
75
|
try {
|
|
71
76
|
// Derive outputs + grid from the (current) input shapes when a function is
|
|
72
77
|
// given — so the SAME kernel object answers correctly for any input shape
|
|
@@ -76,6 +81,7 @@ export class MetalKernel {
|
|
|
76
81
|
const grid = typeof call.grid === "function" ? call.grid(inputs) : call.grid;
|
|
77
82
|
for (const o of outputs) {
|
|
78
83
|
const shape = new Int32Array(o.shape);
|
|
84
|
+
keepAlive.push(shape);
|
|
79
85
|
if (C.mlx_fast_metal_kernel_config_add_output_arg(cfg, ptr(shape), BigInt(o.shape.length), o.dtype) !== 0)
|
|
80
86
|
throw new Error(`metal_kernel add_output_arg failed: ${takeMlxError() ?? ""}`);
|
|
81
87
|
}
|
|
@@ -85,19 +91,26 @@ export class MetalKernel {
|
|
|
85
91
|
C.mlx_fast_metal_kernel_config_set_init_value(cfg, call.initValue);
|
|
86
92
|
for (const [k, v] of Object.entries(call.templateInts ?? {})) {
|
|
87
93
|
const kb = Buffer.from(k + "\0", "utf8");
|
|
94
|
+
keepAlive.push(kb);
|
|
88
95
|
C.mlx_fast_metal_kernel_config_add_template_arg_int(cfg, ptr(kb), v);
|
|
89
96
|
}
|
|
90
97
|
for (const [k, v] of Object.entries(call.templateDtypes ?? {})) {
|
|
91
98
|
const kb = Buffer.from(k + "\0", "utf8");
|
|
99
|
+
keepAlive.push(kb);
|
|
92
100
|
C.mlx_fast_metal_kernel_config_add_template_arg_dtype(cfg, ptr(kb), v);
|
|
93
101
|
}
|
|
94
102
|
|
|
95
103
|
const handles = new BigUint64Array(inputs.map((a) => a.handle));
|
|
104
|
+
keepAlive.push(handles);
|
|
96
105
|
const inVec = C.mlx_vector_array_new_data(ptr(handles), BigInt(inputs.length));
|
|
97
106
|
const slot = new BigUint64Array([C.mlx_vector_array_new()]);
|
|
107
|
+
keepAlive.push(slot);
|
|
98
108
|
const slotPtr = ptr(slot);
|
|
99
109
|
const status = C.mlx_fast_metal_kernel_apply(slotPtr, this.#kernel, inVec, cfg, call.stream ?? gpuStream);
|
|
100
110
|
const outVec = read.u64(slotPtr, 0);
|
|
111
|
+
// anchor: all ptr()'d JS buffers above are done being read by native code by
|
|
112
|
+
// this point; touching keepAlive keeps the JIT from freeing them earlier.
|
|
113
|
+
if (keepAlive.length < 0) throw new Error("unreachable");
|
|
101
114
|
C.mlx_vector_array_free(inVec);
|
|
102
115
|
if (status !== 0) {
|
|
103
116
|
C.mlx_vector_array_free(outVec);
|
|
@@ -29,10 +29,12 @@ function forwardTiles(headDim: number): [number, number] {
|
|
|
29
29
|
throw new Error(`unsupported head_dim=${headDim}`);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
/** uint32 [n] array (matches optiq's shape/causal input dtype).
|
|
32
|
+
/** uint32 [n] array (matches optiq's shape/causal input dtype). COPY into an
|
|
33
|
+
* mlx-owned array (not the pinning fromView) — these tiny kernel-arg arrays are
|
|
34
|
+
* disposed before the lazy kernel evaluates; pinning leaks the host buffer per
|
|
35
|
+
* call (see flash-cce.ts u32 for the full diagnosis). */
|
|
33
36
|
function u32(values: number[]): MlxArray {
|
|
34
|
-
|
|
35
|
-
return MlxArray.fromView(new Uint8Array(u.buffer.slice(0)), [values.length], Dtype.uint32);
|
|
37
|
+
return MlxArray.fromBytesCopy(new Uint8Array(new Uint32Array(values).buffer), [values.length], Dtype.uint32);
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
// Forward shader — verbatim from optiq flash_attention_metal.py _KERNEL_SOURCE.
|
package/src/pi-provider.ts
CHANGED
|
@@ -40,6 +40,13 @@ export interface PiProviderOptions {
|
|
|
40
40
|
* reasoning and sends the on/off switch the server maps to enable_thinking.
|
|
41
41
|
* Default false. */
|
|
42
42
|
reasoning?: boolean;
|
|
43
|
+
/** The loaded model can accept images (server's `ctx.vision != null`).
|
|
44
|
+
* This MUST match the real model: pi-ai serializes user content as OpenAI
|
|
45
|
+
* multimodal content-parts (`[{type:"text",…}]`) for image-capable models
|
|
46
|
+
* and as a plain string otherwise. A text-only chat template renders nothing
|
|
47
|
+
* for a parts array, so declaring a non-vision model as image-capable makes
|
|
48
|
+
* the user's turn vanish ("I don't see any message"). Default false. */
|
|
49
|
+
vision?: boolean;
|
|
43
50
|
}
|
|
44
51
|
|
|
45
52
|
export interface PiProviderWiring {
|
|
@@ -69,19 +76,28 @@ export function buildPiProvider(baseUrl: string, opts: PiProviderOptions = {}):
|
|
|
69
76
|
name: opts.name ?? "mlx-bun (local)",
|
|
70
77
|
api: PI_API,
|
|
71
78
|
reasoning: opts.reasoning ?? false,
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
79
|
+
// Compat flags that make pi emit the wire format our local server's
|
|
80
|
+
// chat templates expect (docs/custom-provider.md "Model Definition
|
|
81
|
+
// Reference"):
|
|
82
|
+
// - supportsDeveloperRole:false → pi sends the system prompt as the
|
|
83
|
+
// `system` role, not `developer` (our templates only know
|
|
84
|
+
// system/user/assistant/tool).
|
|
85
|
+
// - thinkingFormat:"qwen-chat-template" (reasoning models only) → pi
|
|
86
|
+
// sends chat_template_kwargs.enable_thinking, the boolean our
|
|
87
|
+
// Qwen3.5/MiniCPM5 templates gate on. pi computes the boolean from
|
|
88
|
+
// the selected thinking level (off → false), so no thinkingLevelMap.
|
|
89
|
+
compat: {
|
|
90
|
+
supportsDeveloperRole: false,
|
|
91
|
+
...(opts.reasoning ? { thinkingFormat: "qwen-chat-template" as const } : {}),
|
|
92
|
+
},
|
|
93
|
+
// input MUST match the loaded model. pi-ai serializes user content as a
|
|
94
|
+
// plain string for text-only models and as OpenAI content-parts
|
|
95
|
+
// (`[{type:"text",…}]`) once a model declares image input — and a
|
|
96
|
+
// text-only chat template renders NOTHING for a parts array, dropping
|
|
97
|
+
// the user's turn ("I don't see any message"). So declare image input
|
|
98
|
+
// only for an actual vision model; the web `ready` frame's `vision`
|
|
99
|
+
// flag is the same signal that drives the UI's image affordance.
|
|
100
|
+
input: opts.vision ? ["text", "image"] : ["text"],
|
|
85
101
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
86
102
|
contextWindow: opts.contextWindow ?? DEFAULT_CONTEXT_WINDOW,
|
|
87
103
|
maxTokens: opts.maxTokens ?? DEFAULT_MAX_TOKENS,
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// Shared pi front-door assembly for mlx-bun's embedded web + terminal agents.
|
|
2
|
+
//
|
|
3
|
+
// This is the single place that decides which custom tools and bundled skills
|
|
4
|
+
// are visible to pi. Keeping that policy here prevents the browser and TUI from
|
|
5
|
+
// drifting — especially for personal memory, whose prompt surface must be
|
|
6
|
+
// relevant-but-not-dominant.
|
|
7
|
+
|
|
8
|
+
import type { ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
9
|
+
import { createWebTools, WEB_TOOL_NAMES } from "./web-tools";
|
|
10
|
+
import { materializeBundledSkillPaths } from "./web/skills";
|
|
11
|
+
import {
|
|
12
|
+
createMemoryTools,
|
|
13
|
+
MEMORY_TOOL_NAMES,
|
|
14
|
+
memoryIndexHint,
|
|
15
|
+
isMemoryEnabled,
|
|
16
|
+
createReferenceTools,
|
|
17
|
+
REFERENCE_TOOL_NAMES,
|
|
18
|
+
} from "./memory/tools";
|
|
19
|
+
|
|
20
|
+
/** Built-in pi coding tools plus mlx-bun's non-mutating web tools. */
|
|
21
|
+
export const PI_BASE_TOOL_NAMES = ["read", "bash", "edit", "write", "grep", "find", "ls", ...WEB_TOOL_NAMES] as const;
|
|
22
|
+
|
|
23
|
+
export interface PiAgentSurfaceOptions {
|
|
24
|
+
/** Force memory on/off for tests. Default: auto-detect vault existence. */
|
|
25
|
+
memory?: "auto" | "on" | "off";
|
|
26
|
+
/** Include web_search/web_fetch/weather. Default true. */
|
|
27
|
+
webTools?: boolean;
|
|
28
|
+
/** Include read/bash/edit/write/grep/find/ls. Default true. */
|
|
29
|
+
codingTools?: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface PiAgentSurface {
|
|
33
|
+
memoryEnabled: boolean;
|
|
34
|
+
/** Tool allowlist to pass to createAgentSession/createAgentSessionFromServices. */
|
|
35
|
+
tools: string[];
|
|
36
|
+
/** Custom tools to pass to pi. Built-ins are selected by name in `tools`. */
|
|
37
|
+
customTools: ToolDefinition[];
|
|
38
|
+
/** Skill paths for DefaultResourceLoader.additionalSkillPaths. */
|
|
39
|
+
skillPaths: string[];
|
|
40
|
+
/** Short prompt addendum. Empty unless memory is enabled. */
|
|
41
|
+
memoryHint: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function resolveMemoryEnabled(mode: PiAgentSurfaceOptions["memory"]): Promise<boolean> {
|
|
45
|
+
if (mode === "on") return true;
|
|
46
|
+
if (mode === "off") return false;
|
|
47
|
+
return isMemoryEnabled();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Build the shared tool + skill surface for both pi front doors.
|
|
52
|
+
*
|
|
53
|
+
* Memory policy: if the user enabled memory (vault exists), memory is available.
|
|
54
|
+
* It is still a scoped retrieval capability, not a default first step for every
|
|
55
|
+
* prompt. If memory is absent, no memory skill/tool schemas are exposed at all.
|
|
56
|
+
*/
|
|
57
|
+
export async function buildPiAgentSurface(opts: PiAgentSurfaceOptions = {}): Promise<PiAgentSurface> {
|
|
58
|
+
const memoryEnabled = await resolveMemoryEnabled(opts.memory ?? "auto");
|
|
59
|
+
const includeWeb = opts.webTools ?? true;
|
|
60
|
+
const includeCoding = opts.codingTools ?? true;
|
|
61
|
+
|
|
62
|
+
const tools: string[] = [];
|
|
63
|
+
if (includeCoding) tools.push("read", "bash", "edit", "write", "grep", "find", "ls");
|
|
64
|
+
const customTools: ToolDefinition[] = [];
|
|
65
|
+
if (includeWeb) {
|
|
66
|
+
tools.push(...WEB_TOOL_NAMES);
|
|
67
|
+
customTools.push(...createWebTools());
|
|
68
|
+
}
|
|
69
|
+
if (memoryEnabled) {
|
|
70
|
+
tools.push(...MEMORY_TOOL_NAMES, ...REFERENCE_TOOL_NAMES);
|
|
71
|
+
customTools.push(...createMemoryTools(), ...createReferenceTools());
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
memoryEnabled,
|
|
76
|
+
tools,
|
|
77
|
+
customTools,
|
|
78
|
+
skillPaths: materializeBundledSkillPaths({ includeMemory: memoryEnabled }),
|
|
79
|
+
memoryHint: memoryEnabled ? await memoryIndexHint() : "",
|
|
80
|
+
};
|
|
81
|
+
}
|
package/src/pi-terminal.ts
CHANGED
|
@@ -35,8 +35,7 @@ import {
|
|
|
35
35
|
runRpcMode,
|
|
36
36
|
type CreateAgentSessionRuntimeFactory,
|
|
37
37
|
} from "@earendil-works/pi-coding-agent";
|
|
38
|
-
import {
|
|
39
|
-
import { materializeBundledSkills } from "./web/skills";
|
|
38
|
+
import { buildPiAgentSurface } from "./pi-session";
|
|
40
39
|
import { buildPiProvider, DEFAULT_CONTEXT_WINDOW } from "./pi-provider";
|
|
41
40
|
|
|
42
41
|
/** How the embedded agent runs. Mirrors pi's CLI appMode. */
|
|
@@ -49,8 +48,6 @@ export type PiTerminalMode = "interactive" | "print" | "rpc";
|
|
|
49
48
|
* sees it. Mutating tools (bash/edit/write) surface pi's own TUI approval
|
|
50
49
|
* prompt at call time — we don't add a gate.
|
|
51
50
|
*/
|
|
52
|
-
const ALL_TOOLS = ["read", "bash", "edit", "write", "grep", "find", "ls", ...WEB_TOOL_NAMES];
|
|
53
|
-
|
|
54
51
|
/**
|
|
55
52
|
* System prompt for the embedded terminal coding agent.
|
|
56
53
|
*
|
|
@@ -70,20 +67,11 @@ export function buildTerminalSystemPrompt(modelLabel?: string): string {
|
|
|
70
67
|
const model = modelLabel ? `the local model \`${modelLabel}\`` : "a local model";
|
|
71
68
|
return `You are mlx-bun's terminal coding agent — a capable, hands-on pair programmer working alongside the user in their terminal. You run on ${model} entirely on the user's own Apple-silicon Mac via mlx-bun, so the whole session stays local and private; nothing leaves the machine except the explicit web tools below.
|
|
72
69
|
|
|
73
|
-
You operate inside the user's current project directory
|
|
74
|
-
|
|
75
|
-
Tools used freely (no confirmation needed):
|
|
76
|
-
- read — open and read any file
|
|
77
|
-
- ls, find, grep — list directories and search the tree by name or content
|
|
78
|
-
- web_search — search the web for current, real-world information (docs, APIs, errors, anything that changes or that you don't already know)
|
|
79
|
-
- web_fetch — fetch a URL and read the page or data behind it (a natural follow-up to web_search, or when the user gives you a link)
|
|
80
|
-
- weather — current conditions and a short forecast for any place
|
|
70
|
+
You operate inside the user's current project directory. Available capabilities when relevant: read-only file inspection (read, ls, find, grep), web search/fetch (web_search, web_fetch), weather, and user-approved local actions (bash, edit, write).
|
|
81
71
|
|
|
82
|
-
|
|
83
|
-
- bash — run shell commands (build, test, git, scripts)
|
|
84
|
-
- edit, write — modify existing files or create new ones
|
|
72
|
+
Use tools in service of helping the user, not as a performance. For ordinary social conversation, answer naturally yourself. For real-world facts, current events, schedules, releases, local information, recommendations, restaurants, movies, prices, travel, docs, or anything likely to have changed, look it up with web_search/web_fetch or weather instead of relying on memory or guessing. For coding tasks, inspect the files, investigate before you answer, and follow through to a working result. When you need to change code or run something, propose the concrete edit or command and let the approval prompt handle consent — don't ask permission in prose first.
|
|
85
73
|
|
|
86
|
-
|
|
74
|
+
Environment metadata such as current date, working directory, model name, and available tools may be provided for context; do not report or summarize that metadata unless the user asks for it or it is directly relevant. Do not narrate tool policies or internal workflows.
|
|
87
75
|
|
|
88
76
|
Be honest about what you did and what you found, including mistakes, dead ends, and anything you couldn't do. Keep responses tight and skimmable: format with Markdown, show file paths and commands plainly, and cite links when you used the web.`;
|
|
89
77
|
}
|
|
@@ -121,6 +109,7 @@ export async function runEmbeddedPi(opts: RunEmbeddedPiOptions): Promise<number>
|
|
|
121
109
|
const cwd = process.cwd();
|
|
122
110
|
// Own session/settings dir, isolated from any standalone pi install.
|
|
123
111
|
const agentDir = join(homedir(), ".mlx-bun", "pi");
|
|
112
|
+
const sessionDir = join(agentDir, "sessions", `--${cwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`);
|
|
124
113
|
|
|
125
114
|
const { authStorage, modelRegistry, model } = buildPiProvider(opts.baseUrl, {
|
|
126
115
|
contextWindow: opts.contextWindow ?? DEFAULT_CONTEXT_WINDOW,
|
|
@@ -128,10 +117,10 @@ export async function runEmbeddedPi(opts: RunEmbeddedPiOptions): Promise<number>
|
|
|
128
117
|
reasoning: opts.reasoning ?? false,
|
|
129
118
|
});
|
|
130
119
|
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
const
|
|
134
|
-
const systemPrompt = buildTerminalSystemPrompt(opts.modelLabel);
|
|
120
|
+
// Shared pi tool/skill surface. Memory is included only when the user has
|
|
121
|
+
// enabled a vault; if present it remains scoped to user-specific continuity.
|
|
122
|
+
const surface = await buildPiAgentSurface();
|
|
123
|
+
const systemPrompt = buildTerminalSystemPrompt(opts.modelLabel) + surface.memoryHint;
|
|
135
124
|
|
|
136
125
|
// The runtime factory: same shape as pi's own CLI (dist/main.js) and the
|
|
137
126
|
// shipped examples/sdk/13-session-runtime.ts. The same factory is reused by
|
|
@@ -154,7 +143,7 @@ export async function runEmbeddedPi(opts: RunEmbeddedPiOptions): Promise<number>
|
|
|
154
143
|
// AGENTS.md / CLAUDE.md context files (unlike the web chat).
|
|
155
144
|
noContextFiles: false,
|
|
156
145
|
// Our curated skills on top (noSkills above only disables discovery).
|
|
157
|
-
additionalSkillPaths:
|
|
146
|
+
additionalSkillPaths: surface.skillPaths,
|
|
158
147
|
// Replace pi's default coding-agent prompt with our mlx-bun persona.
|
|
159
148
|
systemPrompt,
|
|
160
149
|
},
|
|
@@ -165,15 +154,15 @@ export async function runEmbeddedPi(opts: RunEmbeddedPiOptions): Promise<number>
|
|
|
165
154
|
sessionManager,
|
|
166
155
|
sessionStartEvent,
|
|
167
156
|
model,
|
|
168
|
-
tools:
|
|
169
|
-
customTools:
|
|
157
|
+
tools: surface.tools,
|
|
158
|
+
customTools: surface.customTools,
|
|
170
159
|
})),
|
|
171
160
|
services,
|
|
172
161
|
diagnostics: services.diagnostics,
|
|
173
162
|
};
|
|
174
163
|
};
|
|
175
164
|
|
|
176
|
-
const sessionManager = SessionManager.create(cwd);
|
|
165
|
+
const sessionManager = SessionManager.create(cwd, sessionDir);
|
|
177
166
|
const runtime = await createAgentSessionRuntime(createRuntime, { cwd, agentDir, sessionManager });
|
|
178
167
|
|
|
179
168
|
try {
|