@north-light/crouter 0.3.218 → 0.3.219
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/dist/clients/attach/viewer.js +368 -368
- package/dist/core/runtime/launch-config-worker.d.ts +1 -0
- package/dist/core/runtime/launch-config-worker.js +12 -0
- package/dist/core/runtime/launch.d.ts +16 -2
- package/dist/core/runtime/launch.js +55 -21
- package/dist/core/runtime/promote.d.ts +20 -2
- package/dist/core/runtime/promote.js +63 -59
- package/dist/core/runtime/recycle.js +2 -2
- package/dist/core/runtime/reset.js +2 -2
- package/dist/core/runtime/spawn.js +3 -3
- package/dist/core/runtime/warm-pool.js +9 -7
- package/dist/daemon/api/__tests__/bridge-heartbeat.test.d.ts +1 -0
- package/dist/daemon/api/__tests__/bridge-heartbeat.test.js +30 -0
- package/dist/daemon/api/__tests__/seam/api-server.test.js +30 -0
- package/dist/daemon/api/bridge.d.ts +6 -0
- package/dist/daemon/api/bridge.js +39 -2
- package/dist/daemon/api/handlers/nodes.js +16 -17
- package/package.json +1 -1
- package/runtime.lock.json +2 -2
|
@@ -19,15 +19,14 @@ import { nodeArtifacts } from '../../../core/canvas/history.js';
|
|
|
19
19
|
import { readNodeMessagesPage, readNodeSession, readNodeSnapshot, transcriptMarkdown } from '../../../core/runtime/node-read.js';
|
|
20
20
|
import { assembleNodeSubject } from '../../../core/substrate/subject.js';
|
|
21
21
|
import { reviveAll } from '../../../core/runtime/revive-all.js';
|
|
22
|
-
import {
|
|
22
|
+
import { promoteAsync, requestYieldAsync, reshapeNodeAsync } from '../../../core/runtime/promote.js';
|
|
23
23
|
import { recycleNode } from '../../../core/runtime/recycle.js';
|
|
24
24
|
import { relaunchRoot } from '../../../core/runtime/reset.js';
|
|
25
25
|
import { assertReopenGate } from '../../../core/runtime/reopen.js';
|
|
26
26
|
import { writeYieldMessage, readGoal } from '../../../core/runtime/kickoff.js';
|
|
27
27
|
import { hasRoadmap, seedRoadmap } from '../../../core/runtime/roadmap.js';
|
|
28
28
|
import { renameWindow } from '../../../core/runtime/placement.js';
|
|
29
|
-
import {
|
|
30
|
-
import { buildLaunchSpec, isProviderPinnedModelToken, normalizeModel } from '../../../core/runtime/launch.js';
|
|
29
|
+
import { buildLaunchSpecAsync, isProviderPinnedModelToken, normalizeModel, readMergedLaunchConfigAsync } from '../../../core/runtime/launch.js';
|
|
31
30
|
import { modelRequestFromConfig } from '../../../core/model-routes.js';
|
|
32
31
|
import { BrokerUnreachableError } from '../../../core/runtime/broker-request.js';
|
|
33
32
|
import { isBrokerLive, persistDormantModel, setModelLive } from '../../../core/runtime/model-swap.js';
|
|
@@ -196,13 +195,13 @@ function requestFromLaunch(launch) {
|
|
|
196
195
|
return modelRequestFromConfig(launch.model, intent, launch.modelExact === true);
|
|
197
196
|
}
|
|
198
197
|
async function assertNodeModelChangeRegistered(meta, target, registry) {
|
|
199
|
-
const launch =
|
|
198
|
+
const launch = (await buildLaunchSpecAsync(target.kind, target.mode, {
|
|
200
199
|
lifecycle: target.lifecycle,
|
|
201
200
|
hasManager: meta.parent !== null,
|
|
202
201
|
model: target.model,
|
|
203
202
|
cwd: meta.cwd,
|
|
204
203
|
profileId: meta.profile_id ?? null,
|
|
205
|
-
}).launch;
|
|
204
|
+
})).launch;
|
|
206
205
|
await assertLaunchModelRegistered(requestFromLaunch(launch), { cwd: meta.cwd, profileId: meta.profile_id ?? null }, registry);
|
|
207
206
|
}
|
|
208
207
|
export async function handleCreate(ctx, deps = {}) {
|
|
@@ -234,16 +233,16 @@ export async function handleCreate(ctx, deps = {}) {
|
|
|
234
233
|
const profileId = await resolveProfileId(req.profile, parent ?? null, contextCwd);
|
|
235
234
|
const profile = assertProfileActive(profileId);
|
|
236
235
|
const kind = resolveCreateKind(req.kind, profile);
|
|
237
|
-
assertKindServer(kind);
|
|
238
236
|
const resolvedReq = { ...req, kind };
|
|
239
237
|
const cwd = resolveNodeCwd(resolvedReq, parent, profileId, contextCwd);
|
|
240
|
-
|
|
238
|
+
await assertKindServer(kind, cwd, profileId);
|
|
239
|
+
const launch = (await buildLaunchSpecAsync(kind, (resolvedReq.mode ?? 'base'), {
|
|
241
240
|
lifecycle: req.root === true ? (req.root_lifecycle ?? 'resident') : 'terminal',
|
|
242
241
|
hasManager: req.root !== true,
|
|
243
242
|
...(req.model !== undefined ? { model: req.model } : {}),
|
|
244
243
|
cwd,
|
|
245
244
|
profileId,
|
|
246
|
-
}).launch;
|
|
245
|
+
})).launch;
|
|
247
246
|
await assertLaunchModelRegistered(requestFromLaunch(launch), { cwd, profileId }, deps.modelRegistry);
|
|
248
247
|
// --- Warm path: hand out an already-booted spare instead of paying a full
|
|
249
248
|
// engine boot. A miss is not a failure — it falls through to the cold
|
|
@@ -555,12 +554,12 @@ async function handleRecycle(ctx) {
|
|
|
555
554
|
},
|
|
556
555
|
};
|
|
557
556
|
}
|
|
558
|
-
function handleDemote(ctx) {
|
|
557
|
+
async function handleDemote(ctx) {
|
|
559
558
|
const id = ctx.params['id'];
|
|
560
559
|
requireMeta(id);
|
|
561
560
|
// Use the canonical reshape primitive to ensure modelExact, provider
|
|
562
561
|
// pin/intent, and default-name migration are all preserved.
|
|
563
|
-
|
|
562
|
+
await reshapeNodeAsync(id, { lifecycle: 'terminal' });
|
|
564
563
|
return { status: 200, body: detailOf(id) };
|
|
565
564
|
}
|
|
566
565
|
export async function handlePromote(ctx, deps = {}) {
|
|
@@ -575,7 +574,7 @@ export async function handlePromote(ctx, deps = {}) {
|
|
|
575
574
|
model: req.model,
|
|
576
575
|
}, deps.modelRegistry);
|
|
577
576
|
}
|
|
578
|
-
const result =
|
|
577
|
+
const result = await promoteAsync(id, {
|
|
579
578
|
...(req.kind !== undefined ? { kind: req.kind } : {}),
|
|
580
579
|
...(req.resident === true ? { resident: true } : {}),
|
|
581
580
|
...(req.model !== undefined ? { model: req.model } : {}),
|
|
@@ -602,7 +601,7 @@ export async function handleYield(ctx, deps = {}) {
|
|
|
602
601
|
}
|
|
603
602
|
const note = req.note ?? 'Refresh: continue against your roadmap or goal.';
|
|
604
603
|
writeYieldMessage(id, note);
|
|
605
|
-
const result =
|
|
604
|
+
const result = await requestYieldAsync(id, {
|
|
606
605
|
...(req.promote === true ? { promote: true } : {}),
|
|
607
606
|
...(req.kind !== undefined ? { kind: req.kind } : {}),
|
|
608
607
|
...(req.model !== undefined ? { model: req.model } : {}),
|
|
@@ -645,7 +644,7 @@ export async function handleConfig(ctx, deps = {}) {
|
|
|
645
644
|
}
|
|
646
645
|
if (patch.model !== undefined) {
|
|
647
646
|
const pinned = isProviderPinnedModelToken(patch.model);
|
|
648
|
-
const ladders =
|
|
647
|
+
const ladders = (await readMergedLaunchConfigAsync(meta.cwd, meta.profile_id ?? null)).modelLadders;
|
|
649
648
|
const spec = normalizeModel(patch.model, ladders);
|
|
650
649
|
await assertLaunchModelRegistered({ kind: 'concrete', spec }, { cwd: meta.cwd, profileId: meta.profile_id ?? null }, deps.modelRegistry);
|
|
651
650
|
const persistDormant = () => {
|
|
@@ -681,7 +680,7 @@ export async function handleConfig(ctx, deps = {}) {
|
|
|
681
680
|
// --- kind / mode / lifecycle: reshape via canonical primitive (CLI parity). ---
|
|
682
681
|
if (patch.kind !== undefined || patch.mode !== undefined || patch.lifecycle !== undefined) {
|
|
683
682
|
if (patch.kind !== undefined)
|
|
684
|
-
assertKindServer(patch.kind);
|
|
683
|
+
await assertKindServer(patch.kind, meta.cwd, meta.profile_id ?? null);
|
|
685
684
|
const newKind = patch.kind ?? meta.kind;
|
|
686
685
|
const newMode = (patch.mode ?? meta.mode);
|
|
687
686
|
const newLifecycle = patch.lifecycle ?? meta.lifecycle;
|
|
@@ -697,7 +696,7 @@ export async function handleConfig(ctx, deps = {}) {
|
|
|
697
696
|
}
|
|
698
697
|
// Use canonical reshape primitive to preserve modelExact, provider pin/intent,
|
|
699
698
|
// and default-name migration.
|
|
700
|
-
meta =
|
|
699
|
+
meta = await reshapeNodeAsync(id, {
|
|
701
700
|
...(patch.kind !== undefined ? { kind: newKind } : {}),
|
|
702
701
|
...(patch.mode !== undefined ? { mode: newMode } : {}),
|
|
703
702
|
...(patch.lifecycle !== undefined ? { lifecycle: newLifecycle } : {}),
|
|
@@ -715,8 +714,8 @@ export async function handleConfig(ctx, deps = {}) {
|
|
|
715
714
|
}
|
|
716
715
|
/** Validate a `--kind` against the installed personas server-side (crtrd reads
|
|
717
716
|
* the merged launch config). Mirrors the CLI's assertKind. */
|
|
718
|
-
function assertKindServer(kind) {
|
|
719
|
-
const kinds = Object.keys(
|
|
717
|
+
async function assertKindServer(kind, cwd, profileId) {
|
|
718
|
+
const kinds = Object.keys((await readMergedLaunchConfigAsync(cwd, profileId)).kinds);
|
|
720
719
|
if (!kinds.includes(kind)) {
|
|
721
720
|
throw usage(`unknown kind: ${kind}`, { received: kind, next: `Valid kinds: ${kinds.sort().join(', ')}.` });
|
|
722
721
|
}
|
package/package.json
CHANGED
package/runtime.lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/crouter",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.219",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@north-light/crouter",
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.219",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"dependencies": {
|