@spencerboucher/switchyard 0.5.0 → 0.6.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 +4 -2
- package/dist/bridge/pi-model.js +44 -0
- package/dist/bridge/switchyard-bridge.js +24 -2
- package/dist/bridge/switchyard-terminal.js +84 -3
- package/dist/switchyard.mjs +404 -29
- package/package.json +1 -1
- package/web-dist/assets/{AutomationView-CFohp0SQ.js → AutomationView-DgZn3ltn.js} +2 -2
- package/web-dist/assets/{AutomationView-CFohp0SQ.js.map → AutomationView-DgZn3ltn.js.map} +1 -1
- package/web-dist/assets/{InteractionCard-B-xmpTNG.js → InteractionCard-cvPWKSu1.js} +2 -2
- package/web-dist/assets/{InteractionCard-B-xmpTNG.js.map → InteractionCard-cvPWKSu1.js.map} +1 -1
- package/web-dist/assets/{Menu-C4GUY_ym.js → Menu-GymfuHGP.js} +2 -2
- package/web-dist/assets/Menu-GymfuHGP.js.map +1 -0
- package/web-dist/assets/{Overlay--v0ur2lj.js → Overlay-oYnnwvFM.js} +2 -2
- package/web-dist/assets/{Overlay--v0ur2lj.js.map → Overlay-oYnnwvFM.js.map} +1 -1
- package/web-dist/assets/{attention-q6_xlnT4.js → attention-Bxg9W15n.js} +2 -2
- package/web-dist/assets/{attention-q6_xlnT4.js.map → attention-Bxg9W15n.js.map} +1 -1
- package/web-dist/assets/{automations-CyA83OAD.js → automations-DdB97dnL.js} +2 -2
- package/web-dist/assets/{automations-CyA83OAD.js.map → automations-DdB97dnL.js.map} +1 -1
- package/web-dist/assets/{board-BFvNcFhk.js → board-s4LuDPcg.js} +2 -2
- package/web-dist/assets/{board-BFvNcFhk.js.map → board-s4LuDPcg.js.map} +1 -1
- package/web-dist/assets/code-B0KXn7lD.js +8 -0
- package/web-dist/assets/code-B0KXn7lD.js.map +1 -0
- package/web-dist/assets/{describe-BirsjlUl.js → describe-C_3FJuSs.js} +2 -2
- package/web-dist/assets/{describe-BirsjlUl.js.map → describe-C_3FJuSs.js.map} +1 -1
- package/web-dist/assets/dist-Bgkh2hc5.js +56 -0
- package/web-dist/assets/dist-Bgkh2hc5.js.map +1 -0
- package/web-dist/assets/{enroll-C7UBC20s.js → enroll-DijmoolY.js} +2 -2
- package/web-dist/assets/{enroll-C7UBC20s.js.map → enroll-DijmoolY.js.map} +1 -1
- package/web-dist/assets/index-C5n2QB-Y.css +2 -0
- package/web-dist/assets/{index-IdzOP9GE.js → index-Cf6ZUCfK.js} +3 -3
- package/web-dist/assets/{index-IdzOP9GE.js.map → index-Cf6ZUCfK.js.map} +1 -1
- package/web-dist/assets/{more-syTnSpW3.js → more-CRGJsz6E.js} +2 -2
- package/web-dist/assets/{more-syTnSpW3.js.map → more-CRGJsz6E.js.map} +1 -1
- package/web-dist/assets/{now-BqsLS-tK.js → now-D6lDofYy.js} +2 -2
- package/web-dist/assets/{now-BqsLS-tK.js.map → now-D6lDofYy.js.map} +1 -1
- package/web-dist/assets/{settings-DRj7UPtP.js → settings-Csal1F-W.js} +6 -6
- package/web-dist/assets/settings-Csal1F-W.js.map +1 -0
- package/web-dist/assets/{useNow-BQpDYijR.js → useNow-Bc_NlDY3.js} +2 -2
- package/web-dist/assets/{useNow-BQpDYijR.js.map → useNow-Bc_NlDY3.js.map} +1 -1
- package/web-dist/index.html +2 -2
- package/web-dist/sw.js +1 -1
- package/web-dist/assets/Menu-C4GUY_ym.js.map +0 -1
- package/web-dist/assets/code-DavnmlQN.js +0 -8
- package/web-dist/assets/code-DavnmlQN.js.map +0 -1
- package/web-dist/assets/dist-C-h8FC-n.js +0 -56
- package/web-dist/assets/dist-C-h8FC-n.js.map +0 -1
- package/web-dist/assets/index-ByiuDoG0.css +0 -2
- package/web-dist/assets/settings-DRj7UPtP.js.map +0 -1
package/dist/switchyard.mjs
CHANGED
|
@@ -283,6 +283,8 @@ var RuntimeCapabilities = z3.object({
|
|
|
283
283
|
costAccounting: z3.boolean(),
|
|
284
284
|
/** The host runs sessions as interactive Pi in a terminal that clients can attach to. */
|
|
285
285
|
terminal: z3.boolean().optional(),
|
|
286
|
+
/** The host answers session.models, session.commands, session.setModel, session.setThinking and session.compact. */
|
|
287
|
+
sessionControls: z3.boolean().optional(),
|
|
286
288
|
unsupported: z3.array(z3.object({ capability: z3.string(), reason: z3.string() }))
|
|
287
289
|
});
|
|
288
290
|
var ProjectScan = z3.object({
|
|
@@ -364,6 +366,28 @@ var Workspace = z3.object({
|
|
|
364
366
|
updatedAt: Iso
|
|
365
367
|
});
|
|
366
368
|
var ThinkingLevel = z3.enum(["off", "minimal", "low", "medium", "high", "xhigh", "max"]);
|
|
369
|
+
var SessionModel = z3.object({
|
|
370
|
+
provider: z3.string(),
|
|
371
|
+
id: z3.string(),
|
|
372
|
+
name: z3.string().nullable(),
|
|
373
|
+
contextWindow: z3.number().nullable(),
|
|
374
|
+
reasoning: z3.boolean(),
|
|
375
|
+
/** In Pi's scoped (favorite) model list; set only when Pi has one. */
|
|
376
|
+
scoped: z3.boolean().optional(),
|
|
377
|
+
/** Effort levels this model accepts, in Pi's order; ["off"] without reasoning. */
|
|
378
|
+
thinkingLevels: z3.array(ThinkingLevel)
|
|
379
|
+
});
|
|
380
|
+
var SlashCommand = z3.object({
|
|
381
|
+
name: z3.string().min(1),
|
|
382
|
+
description: z3.string().nullable(),
|
|
383
|
+
source: z3.enum(["extension", "prompt", "skill"])
|
|
384
|
+
});
|
|
385
|
+
var ContextUsage = z3.object({
|
|
386
|
+
/** Estimated tokens in context; null right after compaction until the next reply. */
|
|
387
|
+
tokens: z3.number().nullable(),
|
|
388
|
+
window: z3.number(),
|
|
389
|
+
percent: z3.number().nullable()
|
|
390
|
+
});
|
|
367
391
|
var FORBIDDEN_EXTRA_ARGS = ["--mode", "--fork", "--no-session", "-e", "--extension"];
|
|
368
392
|
var ExtraArg = z3.string().refine((a) => a.startsWith("--") || !a.startsWith("-"), "extra args must be long flags").refine((a) => !FORBIDDEN_EXTRA_ARGS.includes(a.split("=")[0]) && !a.startsWith("--session"), "this flag is managed by Switchyard");
|
|
369
393
|
var Profile = z3.object({
|
|
@@ -373,7 +397,9 @@ var Profile = z3.object({
|
|
|
373
397
|
model: z3.string().nullable(),
|
|
374
398
|
thinking: ThinkingLevel.nullable(),
|
|
375
399
|
projectTrust: z3.enum(["ask", "approve", "ignore"]),
|
|
376
|
-
extraArgs: z3.array(ExtraArg)
|
|
400
|
+
extraArgs: z3.array(ExtraArg),
|
|
401
|
+
/** "vanilla": --no-extensions --no-skills --no-prompt-templates. Undefined means "all". */
|
|
402
|
+
resources: z3.enum(["all", "vanilla"]).optional()
|
|
377
403
|
});
|
|
378
404
|
var RuntimeState = z3.enum([
|
|
379
405
|
"starting",
|
|
@@ -387,7 +413,8 @@ var RuntimeState = z3.enum([
|
|
|
387
413
|
var NativeHandle = z3.object({ sessionId: z3.string(), sessionFile: z3.string() });
|
|
388
414
|
var SessionStats = z3.object({
|
|
389
415
|
tokens: z3.number().nullable(),
|
|
390
|
-
costUsd: z3.number().nullable()
|
|
416
|
+
costUsd: z3.number().nullable(),
|
|
417
|
+
context: ContextUsage.nullable().optional()
|
|
391
418
|
});
|
|
392
419
|
var Session = z3.object({
|
|
393
420
|
id: Id,
|
|
@@ -410,6 +437,12 @@ var Session = z3.object({
|
|
|
410
437
|
archivedAt: Iso.nullable(),
|
|
411
438
|
queue: z3.object({ steering: z3.array(z3.string()), followUp: z3.array(z3.string()) }),
|
|
412
439
|
stats: SessionStats.nullable(),
|
|
440
|
+
/** The live model (host-owned; last known when stopped). */
|
|
441
|
+
model: SessionModel.nullable().optional(),
|
|
442
|
+
/** The live effort (Pi's thinking level). */
|
|
443
|
+
thinking: ThinkingLevel.nullable().optional(),
|
|
444
|
+
/** Pi is compacting the context. */
|
|
445
|
+
compacting: z3.boolean().optional(),
|
|
413
446
|
lastAssistantText: z3.string().nullable(),
|
|
414
447
|
createdAt: Iso,
|
|
415
448
|
/** A live terminal session: `switchyard tui` can attach to its Pi terminal. */
|
|
@@ -848,7 +881,8 @@ var ProfileInput = z4.object({
|
|
|
848
881
|
model: z4.string().nullable().default(null),
|
|
849
882
|
thinking: ThinkingLevel.nullable().default(null),
|
|
850
883
|
projectTrust: z4.enum(["ask", "approve", "ignore"]).default("ask"),
|
|
851
|
-
extraArgs: z4.array(ExtraArg).default([])
|
|
884
|
+
extraArgs: z4.array(ExtraArg).default([]),
|
|
885
|
+
resources: z4.enum(["all", "vanilla"]).default("all")
|
|
852
886
|
});
|
|
853
887
|
var CreateWorkspaceRequest = z4.object({
|
|
854
888
|
checkoutId: z4.string(),
|
|
@@ -879,6 +913,18 @@ var PromptRequest = z4.object({
|
|
|
879
913
|
clientMessageId: z4.string().optional()
|
|
880
914
|
});
|
|
881
915
|
var RenameRequest = z4.object({ title: z4.string().min(1).max(200) });
|
|
916
|
+
var SetModelRequest = z4.object({
|
|
917
|
+
provider: z4.string().min(1),
|
|
918
|
+
modelId: z4.string().min(1)
|
|
919
|
+
});
|
|
920
|
+
var SetThinkingRequest = z4.object({ level: ThinkingLevel });
|
|
921
|
+
var CompactRequest = z4.object({ instructions: z4.string().max(4e3).optional() });
|
|
922
|
+
var SessionModelsResult = z4.object({ models: z4.array(SessionModel) });
|
|
923
|
+
var SessionCommandsResult = z4.object({ commands: z4.array(SlashCommand) });
|
|
924
|
+
var ModelStateResult = z4.object({
|
|
925
|
+
model: SessionModel.nullable(),
|
|
926
|
+
thinking: ThinkingLevel.nullable()
|
|
927
|
+
});
|
|
882
928
|
var ImportSessionRequest = z4.object({
|
|
883
929
|
hostId: z4.string(),
|
|
884
930
|
sessionFile: z4.string(),
|
|
@@ -1253,6 +1299,20 @@ var HostCommand = z8.discriminatedUnion("type", [
|
|
|
1253
1299
|
z8.object({ type: z8.literal("session.importable") }),
|
|
1254
1300
|
z8.object({ type: z8.literal("session.readNative"), sessionFile: z8.string() }),
|
|
1255
1301
|
z8.object({ type: z8.literal("session.snapshot"), sessionId: z8.string() }),
|
|
1302
|
+
z8.object({ type: z8.literal("session.models"), sessionId: z8.string() }),
|
|
1303
|
+
z8.object({ type: z8.literal("session.commands"), sessionId: z8.string() }),
|
|
1304
|
+
z8.object({
|
|
1305
|
+
type: z8.literal("session.setModel"),
|
|
1306
|
+
sessionId: z8.string(),
|
|
1307
|
+
provider: z8.string().min(1),
|
|
1308
|
+
modelId: z8.string().min(1)
|
|
1309
|
+
}),
|
|
1310
|
+
z8.object({ type: z8.literal("session.setThinking"), sessionId: z8.string(), level: ThinkingLevel }),
|
|
1311
|
+
z8.object({
|
|
1312
|
+
type: z8.literal("session.compact"),
|
|
1313
|
+
sessionId: z8.string(),
|
|
1314
|
+
instructions: z8.string().nullable()
|
|
1315
|
+
}),
|
|
1256
1316
|
z8.object({ type: z8.literal("checkout.inspect"), path: z8.string() }),
|
|
1257
1317
|
z8.object({ type: z8.literal("projects.scan"), folder: z8.string().min(1) }),
|
|
1258
1318
|
z8.object({
|
|
@@ -4278,7 +4338,7 @@ function resolveProfile(ctx, profileId, project) {
|
|
|
4278
4338
|
const id = profileId ?? project?.defaultProfileId ?? null;
|
|
4279
4339
|
if (id)
|
|
4280
4340
|
return ctx.store.profiles.require(id);
|
|
4281
|
-
const first = ctx.store.profiles.list(void 0, [], "created_at")[0];
|
|
4341
|
+
const first = ctx.store.profiles.list(void 0, [], "created_at, rowid")[0];
|
|
4282
4342
|
if (!first)
|
|
4283
4343
|
throw new SwitchyardError("invalid_request", "No Pi profile configured");
|
|
4284
4344
|
return first;
|
|
@@ -7437,6 +7497,9 @@ var HOST_SESSION_FIELDS = [
|
|
|
7437
7497
|
"runtimeDetail",
|
|
7438
7498
|
"queue",
|
|
7439
7499
|
"stats",
|
|
7500
|
+
"model",
|
|
7501
|
+
"thinking",
|
|
7502
|
+
"compacting",
|
|
7440
7503
|
"lastAssistantText",
|
|
7441
7504
|
"lastActivityAt",
|
|
7442
7505
|
"terminal"
|
|
@@ -7955,7 +8018,7 @@ var HostHub = class {
|
|
|
7955
8018
|
projectId: ws?.projectId ?? null,
|
|
7956
8019
|
cwd: "",
|
|
7957
8020
|
nativeHandle: null,
|
|
7958
|
-
profileSnapshot: this.store.profiles.list(void 0, [], "created_at")[0] ?? FALLBACK_PROFILE,
|
|
8021
|
+
profileSnapshot: this.store.profiles.list(void 0, [], "created_at, rowid")[0] ?? FALLBACK_PROFILE,
|
|
7959
8022
|
runtime: "idle",
|
|
7960
8023
|
runtimeDetail: null,
|
|
7961
8024
|
runId: null,
|
|
@@ -9133,23 +9196,39 @@ function registerOpsRoutes(app, ctx) {
|
|
|
9133
9196
|
|
|
9134
9197
|
// packages/coordinator/dist/routes/profiles.js
|
|
9135
9198
|
var ProfilePatch = Profile.omit({ id: true }).partial();
|
|
9136
|
-
function
|
|
9199
|
+
function seedDefaultProfiles(ctx) {
|
|
9137
9200
|
ctx.store.tx(() => {
|
|
9138
|
-
if (ctx.store.profiles.count()
|
|
9201
|
+
if (ctx.store.profiles.count() === 0) {
|
|
9202
|
+
ctx.store.putProfile({
|
|
9203
|
+
id: newId("prf"),
|
|
9204
|
+
name: "Default",
|
|
9205
|
+
provider: null,
|
|
9206
|
+
model: null,
|
|
9207
|
+
thinking: null,
|
|
9208
|
+
projectTrust: "ask",
|
|
9209
|
+
extraArgs: []
|
|
9210
|
+
});
|
|
9211
|
+
}
|
|
9212
|
+
if (ctx.store.getSetting("profiles.vanillaSeeded", false))
|
|
9139
9213
|
return;
|
|
9140
|
-
ctx.store.
|
|
9141
|
-
|
|
9142
|
-
|
|
9143
|
-
|
|
9144
|
-
|
|
9145
|
-
|
|
9146
|
-
|
|
9147
|
-
|
|
9148
|
-
|
|
9214
|
+
const has = ctx.store.profiles.list().some((p) => p.resources === "vanilla");
|
|
9215
|
+
if (!has) {
|
|
9216
|
+
ctx.store.putProfile({
|
|
9217
|
+
id: newId("prf"),
|
|
9218
|
+
name: "Vanilla",
|
|
9219
|
+
provider: null,
|
|
9220
|
+
model: null,
|
|
9221
|
+
thinking: null,
|
|
9222
|
+
projectTrust: "ask",
|
|
9223
|
+
extraArgs: [],
|
|
9224
|
+
resources: "vanilla"
|
|
9225
|
+
});
|
|
9226
|
+
}
|
|
9227
|
+
ctx.store.setSetting("profiles.vanillaSeeded", true);
|
|
9149
9228
|
});
|
|
9150
9229
|
}
|
|
9151
9230
|
function registerProfileRoutes(app, ctx) {
|
|
9152
|
-
app.get("/api/profiles", async () => ctx.store.profiles.list(void 0, [], "created_at"));
|
|
9231
|
+
app.get("/api/profiles", async () => ctx.store.profiles.list(void 0, [], "created_at, rowid"));
|
|
9153
9232
|
app.get("/api/profiles/:id", async (req) => ctx.store.profiles.require(req.params.id));
|
|
9154
9233
|
app.post("/api/profiles", async (req, reply) => {
|
|
9155
9234
|
const body = parse(ProfileInput, req.body);
|
|
@@ -9316,6 +9395,20 @@ function registerProjectRoutes(app, ctx) {
|
|
|
9316
9395
|
|
|
9317
9396
|
// packages/coordinator/dist/routes/sessions.js
|
|
9318
9397
|
import { z as z16 } from "zod";
|
|
9398
|
+
function requireLiveSession(ctx, s) {
|
|
9399
|
+
if (s.readOnly)
|
|
9400
|
+
throw new SwitchyardError("forbidden", SUBAGENT_READ_ONLY);
|
|
9401
|
+
if (!LIVE_RUNTIMES2.includes(s.runtime) || s.runtime === "starting") {
|
|
9402
|
+
throw new SwitchyardError("conflict", s.runtime === "starting" ? "Session is still starting" : `Session ${s.runtime}: Resume to send`);
|
|
9403
|
+
}
|
|
9404
|
+
requireConnected(ctx, s.hostId);
|
|
9405
|
+
}
|
|
9406
|
+
function requireSessionControls(ctx, s) {
|
|
9407
|
+
requireLiveSession(ctx, s);
|
|
9408
|
+
if (ctx.store.hosts.get(s.hostId)?.capabilities?.sessionControls !== true) {
|
|
9409
|
+
throw new SwitchyardError("invalid_request", "Update Switchyard on this host to change the model, effort or commands from here");
|
|
9410
|
+
}
|
|
9411
|
+
}
|
|
9319
9412
|
var ListQuery5 = z16.object({
|
|
9320
9413
|
projectId: z16.string().optional(),
|
|
9321
9414
|
hostId: z16.string().optional(),
|
|
@@ -9449,12 +9542,7 @@ function registerSessionRoutes(app, ctx) {
|
|
|
9449
9542
|
app.post("/api/sessions/:id/prompt", async (req) => {
|
|
9450
9543
|
const s = get(idOf(req));
|
|
9451
9544
|
const body = parse(PromptRequest, req.body);
|
|
9452
|
-
|
|
9453
|
-
throw new SwitchyardError("forbidden", SUBAGENT_READ_ONLY);
|
|
9454
|
-
if (!LIVE_RUNTIMES2.includes(s.runtime) || s.runtime === "starting") {
|
|
9455
|
-
throw new SwitchyardError("conflict", s.runtime === "starting" ? "Session is still starting" : `Session ${s.runtime}: Resume to send`);
|
|
9456
|
-
}
|
|
9457
|
-
requireConnected(ctx, s.hostId);
|
|
9545
|
+
requireLiveSession(ctx, s);
|
|
9458
9546
|
const run = ctx.store.runForSession(s);
|
|
9459
9547
|
const result = await ctx.hostHub.request(s.hostId, {
|
|
9460
9548
|
type: "session.prompt",
|
|
@@ -9472,6 +9560,53 @@ function registerSessionRoutes(app, ctx) {
|
|
|
9472
9560
|
automationActive: run?.controlMode === "automation"
|
|
9473
9561
|
};
|
|
9474
9562
|
});
|
|
9563
|
+
app.get("/api/sessions/:id/models", async (req) => {
|
|
9564
|
+
const s = get(idOf(req));
|
|
9565
|
+
requireSessionControls(ctx, s);
|
|
9566
|
+
return SessionModelsResult.parse(await ctx.hostHub.request(s.hostId, { type: "session.models", sessionId: s.id }));
|
|
9567
|
+
});
|
|
9568
|
+
app.get("/api/sessions/:id/commands", async (req) => {
|
|
9569
|
+
const s = get(idOf(req));
|
|
9570
|
+
requireSessionControls(ctx, s);
|
|
9571
|
+
return SessionCommandsResult.parse(await ctx.hostHub.request(s.hostId, { type: "session.commands", sessionId: s.id }));
|
|
9572
|
+
});
|
|
9573
|
+
app.post("/api/sessions/:id/model", async (req) => {
|
|
9574
|
+
const s = get(idOf(req));
|
|
9575
|
+
const body = parse(SetModelRequest, req.body);
|
|
9576
|
+
requireSessionControls(ctx, s);
|
|
9577
|
+
return ModelStateResult.parse(await ctx.hostHub.request(s.hostId, {
|
|
9578
|
+
type: "session.setModel",
|
|
9579
|
+
sessionId: s.id,
|
|
9580
|
+
provider: body.provider,
|
|
9581
|
+
modelId: body.modelId
|
|
9582
|
+
}));
|
|
9583
|
+
});
|
|
9584
|
+
app.post("/api/sessions/:id/thinking", async (req) => {
|
|
9585
|
+
const s = get(idOf(req));
|
|
9586
|
+
const body = parse(SetThinkingRequest, req.body);
|
|
9587
|
+
requireSessionControls(ctx, s);
|
|
9588
|
+
return ModelStateResult.parse(await ctx.hostHub.request(s.hostId, {
|
|
9589
|
+
type: "session.setThinking",
|
|
9590
|
+
sessionId: s.id,
|
|
9591
|
+
level: body.level
|
|
9592
|
+
}));
|
|
9593
|
+
});
|
|
9594
|
+
app.post("/api/sessions/:id/compact", async (req) => {
|
|
9595
|
+
const s = get(idOf(req));
|
|
9596
|
+
const body = parse(CompactRequest, req.body ?? {});
|
|
9597
|
+
requireSessionControls(ctx, s);
|
|
9598
|
+
if (s.runtime !== "idle") {
|
|
9599
|
+
throw new SwitchyardError("conflict", "Wait for the run to finish before compacting");
|
|
9600
|
+
}
|
|
9601
|
+
if (s.compacting)
|
|
9602
|
+
throw new SwitchyardError("conflict", "Compaction is already running");
|
|
9603
|
+
await ctx.hostHub.request(s.hostId, {
|
|
9604
|
+
type: "session.compact",
|
|
9605
|
+
sessionId: s.id,
|
|
9606
|
+
instructions: body.instructions?.trim() || null
|
|
9607
|
+
});
|
|
9608
|
+
return { ok: true };
|
|
9609
|
+
});
|
|
9475
9610
|
app.post("/api/sessions/:id/abort", async (req) => {
|
|
9476
9611
|
const s = get(idOf(req));
|
|
9477
9612
|
const body = parse(AbortRequest, req.body);
|
|
@@ -10356,7 +10491,7 @@ var Store2 = class {
|
|
|
10356
10491
|
projects: this.projects.list(void 0, [], "created_at"),
|
|
10357
10492
|
checkouts: this.checkouts.list(),
|
|
10358
10493
|
workspaces: this.workspaces.list("archived_at IS NULL"),
|
|
10359
|
-
profiles: this.profiles.list(void 0, [], "created_at"),
|
|
10494
|
+
profiles: this.profiles.list(void 0, [], "created_at, rowid"),
|
|
10360
10495
|
sessions,
|
|
10361
10496
|
tasks,
|
|
10362
10497
|
runs,
|
|
@@ -10546,7 +10681,7 @@ function createCoordinator(opts) {
|
|
|
10546
10681
|
auth: new RateLimiter(limits ? limits.auth ?? AUTH_RATE_LIMIT : Number.POSITIVE_INFINITY, 6e4, storeClock),
|
|
10547
10682
|
hosts: new RateLimiter(limits ? limits.hosts ?? HOSTS_RATE_LIMIT : Number.POSITIVE_INFINITY, 6e4, storeClock)
|
|
10548
10683
|
};
|
|
10549
|
-
|
|
10684
|
+
seedDefaultProfiles({ store });
|
|
10550
10685
|
const attention = new AttentionService(store, hub);
|
|
10551
10686
|
const hostHub = new HostHub(store, hub, attention, log.child({ mod: "host-hub" }), {
|
|
10552
10687
|
unreachableAfterMs: config.unreachableAfterMs,
|
|
@@ -12776,7 +12911,7 @@ function toErrorBody(err) {
|
|
|
12776
12911
|
function queueKey(command) {
|
|
12777
12912
|
if (command.type === "checks.run")
|
|
12778
12913
|
return `checks:${command.sessionId}`;
|
|
12779
|
-
if (command.type === "session.answer" || command.type === "session.abort" || command.type === "session.setControl" || command.type === "session.adapterAction" || command.type === "session.snapshot") {
|
|
12914
|
+
if (command.type === "session.answer" || command.type === "session.abort" || command.type === "session.setControl" || command.type === "session.adapterAction" || command.type === "session.snapshot" || command.type === "session.models" || command.type === "session.commands") {
|
|
12780
12915
|
return `control:${command.sessionId}`;
|
|
12781
12916
|
}
|
|
12782
12917
|
if ("sessionId" in command && typeof command.sessionId === "string") {
|
|
@@ -12931,6 +13066,16 @@ var CommandRouter = class {
|
|
|
12931
13066
|
return sup.readNative(c.sessionFile);
|
|
12932
13067
|
case "session.snapshot":
|
|
12933
13068
|
return sup.snapshot(c.sessionId);
|
|
13069
|
+
case "session.models":
|
|
13070
|
+
return sup.models(c.sessionId);
|
|
13071
|
+
case "session.commands":
|
|
13072
|
+
return sup.commands(c.sessionId);
|
|
13073
|
+
case "session.setModel":
|
|
13074
|
+
return sup.setModel(c.sessionId, c.provider, c.modelId);
|
|
13075
|
+
case "session.setThinking":
|
|
13076
|
+
return sup.setThinking(c.sessionId, c.level);
|
|
13077
|
+
case "session.compact":
|
|
13078
|
+
return sup.compact(c.sessionId, c.instructions);
|
|
12934
13079
|
case "checkout.inspect":
|
|
12935
13080
|
return inspectCheckout2(c.path);
|
|
12936
13081
|
case "projects.scan":
|
|
@@ -13871,6 +14016,45 @@ function createLogger2(opts = {}) {
|
|
|
13871
14016
|
// packages/host-agent/dist/main.js
|
|
13872
14017
|
import { readFileSync as readFileSync8 } from "node:fs";
|
|
13873
14018
|
|
|
14019
|
+
// packages/pi-runtime/dist/bridge/pi-model.js
|
|
14020
|
+
var PI_THINKING_LEVELS = [
|
|
14021
|
+
"off",
|
|
14022
|
+
"minimal",
|
|
14023
|
+
"low",
|
|
14024
|
+
"medium",
|
|
14025
|
+
"high",
|
|
14026
|
+
"xhigh",
|
|
14027
|
+
"max"
|
|
14028
|
+
];
|
|
14029
|
+
function supportedThinkingLevels(model) {
|
|
14030
|
+
const known = PI_THINKING_LEVELS;
|
|
14031
|
+
if (Array.isArray(model?.thinkingLevels)) {
|
|
14032
|
+
return model.thinkingLevels.filter((l) => typeof l === "string" && known.includes(l));
|
|
14033
|
+
}
|
|
14034
|
+
if (!model?.reasoning)
|
|
14035
|
+
return ["off"];
|
|
14036
|
+
return PI_THINKING_LEVELS.filter((level) => {
|
|
14037
|
+
const mapped = model.thinkingLevelMap?.[level];
|
|
14038
|
+
if (mapped === null)
|
|
14039
|
+
return false;
|
|
14040
|
+
if (level === "xhigh" || level === "max")
|
|
14041
|
+
return mapped !== void 0;
|
|
14042
|
+
return true;
|
|
14043
|
+
});
|
|
14044
|
+
}
|
|
14045
|
+
function modelInfo(model) {
|
|
14046
|
+
if (!model || typeof model.provider !== "string" || typeof model.id !== "string")
|
|
14047
|
+
return null;
|
|
14048
|
+
return {
|
|
14049
|
+
provider: model.provider,
|
|
14050
|
+
id: model.id,
|
|
14051
|
+
name: typeof model.name === "string" && model.name ? model.name : null,
|
|
14052
|
+
contextWindow: typeof model.contextWindow === "number" ? model.contextWindow : null,
|
|
14053
|
+
reasoning: model.reasoning === true,
|
|
14054
|
+
thinkingLevels: supportedThinkingLevels(model)
|
|
14055
|
+
};
|
|
14056
|
+
}
|
|
14057
|
+
|
|
13874
14058
|
// packages/pi-runtime/dist/capabilities.js
|
|
13875
14059
|
import { execFile as execFile2 } from "node:child_process";
|
|
13876
14060
|
import semver from "semver";
|
|
@@ -13889,6 +14073,7 @@ var PI_RPC_CAPABILITIES = {
|
|
|
13889
14073
|
widgetsComponent: false,
|
|
13890
14074
|
tokenAccounting: true,
|
|
13891
14075
|
costAccounting: true,
|
|
14076
|
+
sessionControls: true,
|
|
13892
14077
|
unsupported: [
|
|
13893
14078
|
{ capability: "customUi", reason: "ctx.ui.custom() returns undefined in RPC mode" },
|
|
13894
14079
|
{
|
|
@@ -13912,6 +14097,7 @@ function noCapabilities(reason) {
|
|
|
13912
14097
|
widgetsComponent: false,
|
|
13913
14098
|
tokenAccounting: false,
|
|
13914
14099
|
costAccounting: false,
|
|
14100
|
+
sessionControls: false,
|
|
13915
14101
|
unsupported: [{ capability: "all", reason }]
|
|
13916
14102
|
};
|
|
13917
14103
|
}
|
|
@@ -15099,6 +15285,11 @@ var ManagedSession = class _ManagedSession extends EventEmitter5 {
|
|
|
15099
15285
|
items = /* @__PURE__ */ new Map();
|
|
15100
15286
|
partialToolOutput = /* @__PURE__ */ new Map();
|
|
15101
15287
|
runAssistantText = null;
|
|
15288
|
+
_model = null;
|
|
15289
|
+
scoped = null;
|
|
15290
|
+
_thinking = null;
|
|
15291
|
+
_compacting = false;
|
|
15292
|
+
lastModelJson = "";
|
|
15102
15293
|
constructor(opts) {
|
|
15103
15294
|
super();
|
|
15104
15295
|
this.opts = opts;
|
|
@@ -15149,6 +15340,12 @@ var ManagedSession = class _ManagedSession extends EventEmitter5 {
|
|
|
15149
15340
|
get remoteDialogs() {
|
|
15150
15341
|
return this.proc instanceof PiTerminalProcess ? this.proc.remoteDialogs : true;
|
|
15151
15342
|
}
|
|
15343
|
+
get modelState() {
|
|
15344
|
+
return { model: this._model ? { ...this._model } : null, thinking: this._thinking };
|
|
15345
|
+
}
|
|
15346
|
+
get compacting() {
|
|
15347
|
+
return this._compacting;
|
|
15348
|
+
}
|
|
15152
15349
|
get isAlive() {
|
|
15153
15350
|
return this.proc !== null && this.proc.exited === null;
|
|
15154
15351
|
}
|
|
@@ -15175,6 +15372,9 @@ var ManagedSession = class _ManagedSession extends EventEmitter5 {
|
|
|
15175
15372
|
args.push("--approve");
|
|
15176
15373
|
else if (profile.projectTrust === "ignore")
|
|
15177
15374
|
args.push("--no-approve");
|
|
15375
|
+
if (profile.resources === "vanilla") {
|
|
15376
|
+
args.push("--no-extensions", "--no-skills", "--no-prompt-templates");
|
|
15377
|
+
}
|
|
15178
15378
|
args.push(...profile.extraArgs);
|
|
15179
15379
|
args.push(...this.opts.extraArgs ?? []);
|
|
15180
15380
|
for (const ext of this.opts.extensions ?? [])
|
|
@@ -15245,6 +15445,9 @@ var ManagedSession = class _ManagedSession extends EventEmitter5 {
|
|
|
15245
15445
|
this._native = { sessionId: state.sessionId, sessionFile: state.sessionFile };
|
|
15246
15446
|
this.started = true;
|
|
15247
15447
|
this.busy = state.isStreaming;
|
|
15448
|
+
this.applyModel(state.model);
|
|
15449
|
+
this.applyThinking(state.thinkingLevel);
|
|
15450
|
+
this.emitModelIfChanged();
|
|
15248
15451
|
this.emit("native", { ...this._native });
|
|
15249
15452
|
this.setRuntime();
|
|
15250
15453
|
}
|
|
@@ -15272,6 +15475,9 @@ var ManagedSession = class _ManagedSession extends EventEmitter5 {
|
|
|
15272
15475
|
}
|
|
15273
15476
|
this.started = true;
|
|
15274
15477
|
this.busy = state.isStreaming;
|
|
15478
|
+
this.applyModel(state.model);
|
|
15479
|
+
this.applyThinking(state.thinkingLevel);
|
|
15480
|
+
this.emitModelIfChanged();
|
|
15275
15481
|
this.setRuntime();
|
|
15276
15482
|
}
|
|
15277
15483
|
/** Terminal transport: let go of the holder; Pi keeps running and no exit is reported. */
|
|
@@ -15341,10 +15547,115 @@ var ManagedSession = class _ManagedSession extends EventEmitter5 {
|
|
|
15341
15547
|
async rename(title) {
|
|
15342
15548
|
await this.call(this.requireAlive(), { type: "set_session_name", name: title });
|
|
15343
15549
|
}
|
|
15550
|
+
/** Models Pi can use right now. */
|
|
15551
|
+
async models() {
|
|
15552
|
+
const data = await this.call(this.requireAlive(), {
|
|
15553
|
+
type: "get_available_models"
|
|
15554
|
+
});
|
|
15555
|
+
const out = [];
|
|
15556
|
+
for (const raw of data?.models ?? []) {
|
|
15557
|
+
const m = this.toSessionModel(raw);
|
|
15558
|
+
if (!m)
|
|
15559
|
+
continue;
|
|
15560
|
+
if (this.scoped && this.scoped.size > 0)
|
|
15561
|
+
m.scoped = this.scoped.has(`${m.provider}/${m.id}`);
|
|
15562
|
+
out.push(m);
|
|
15563
|
+
}
|
|
15564
|
+
return out.sort((a, b) => a.provider.localeCompare(b.provider) || (a.name ?? a.id).localeCompare(b.name ?? b.id));
|
|
15565
|
+
}
|
|
15566
|
+
/** Slash commands Pi knows (extension commands, prompt templates, skills). */
|
|
15567
|
+
async commands() {
|
|
15568
|
+
const data = await this.call(this.requireAlive(), {
|
|
15569
|
+
type: "get_commands"
|
|
15570
|
+
});
|
|
15571
|
+
const out = [];
|
|
15572
|
+
for (const c of data?.commands ?? []) {
|
|
15573
|
+
if (typeof c?.name !== "string" || !c.name)
|
|
15574
|
+
continue;
|
|
15575
|
+
if (c.source !== "extension" && c.source !== "prompt" && c.source !== "skill")
|
|
15576
|
+
continue;
|
|
15577
|
+
out.push({
|
|
15578
|
+
name: c.name,
|
|
15579
|
+
description: typeof c.description === "string" ? c.description : null,
|
|
15580
|
+
source: c.source
|
|
15581
|
+
});
|
|
15582
|
+
}
|
|
15583
|
+
return out.sort((a, b) => a.name.localeCompare(b.name));
|
|
15584
|
+
}
|
|
15585
|
+
async setModel(provider, modelId) {
|
|
15586
|
+
await this.call(this.requireAlive(), { type: "set_model", provider, modelId });
|
|
15587
|
+
await this.refreshModelState();
|
|
15588
|
+
return this.modelState;
|
|
15589
|
+
}
|
|
15590
|
+
async setThinking(level) {
|
|
15591
|
+
await this.call(this.requireAlive(), { type: "set_thinking_level", level });
|
|
15592
|
+
await this.refreshModelState();
|
|
15593
|
+
return this.modelState;
|
|
15594
|
+
}
|
|
15595
|
+
/** Start a manual compaction. Terminal sessions answer at once; Pi's RPC answers when done. */
|
|
15596
|
+
async compact(instructions) {
|
|
15597
|
+
const proc = this.requireAlive();
|
|
15598
|
+
const cmd = { type: "compact", ...instructions ? { customInstructions: instructions } : {} };
|
|
15599
|
+
if (this.transport === "terminal") {
|
|
15600
|
+
await this.call(proc, cmd, 1e4);
|
|
15601
|
+
} else {
|
|
15602
|
+
this.call(proc, cmd, 30 * 6e4).catch(() => {
|
|
15603
|
+
});
|
|
15604
|
+
}
|
|
15605
|
+
}
|
|
15606
|
+
async refreshModelState() {
|
|
15607
|
+
const s = await this.state();
|
|
15608
|
+
this.applyModel(s.model);
|
|
15609
|
+
this.applyThinking(s.thinkingLevel);
|
|
15610
|
+
this.emitModelIfChanged();
|
|
15611
|
+
}
|
|
15612
|
+
toSessionModel(raw) {
|
|
15613
|
+
const info = modelInfo(raw);
|
|
15614
|
+
if (!info)
|
|
15615
|
+
return null;
|
|
15616
|
+
return {
|
|
15617
|
+
...info,
|
|
15618
|
+
thinkingLevels: info.thinkingLevels.flatMap((l) => {
|
|
15619
|
+
const r = ThinkingLevel.safeParse(l);
|
|
15620
|
+
return r.success ? [r.data] : [];
|
|
15621
|
+
})
|
|
15622
|
+
};
|
|
15623
|
+
}
|
|
15624
|
+
applyScoped(raw) {
|
|
15625
|
+
if (Array.isArray(raw))
|
|
15626
|
+
this.scoped = new Set(raw.filter((x) => typeof x === "string"));
|
|
15627
|
+
}
|
|
15628
|
+
applyModel(raw) {
|
|
15629
|
+
this._model = this.toSessionModel(raw);
|
|
15630
|
+
}
|
|
15631
|
+
applyThinking(raw) {
|
|
15632
|
+
const r = ThinkingLevel.safeParse(raw);
|
|
15633
|
+
this._thinking = r.success ? r.data : null;
|
|
15634
|
+
}
|
|
15635
|
+
emitModelIfChanged() {
|
|
15636
|
+
const json = JSON.stringify(this.modelState);
|
|
15637
|
+
if (json === this.lastModelJson)
|
|
15638
|
+
return;
|
|
15639
|
+
this.lastModelJson = json;
|
|
15640
|
+
this.emit("model", this.modelState);
|
|
15641
|
+
}
|
|
15642
|
+
setCompacting(v) {
|
|
15643
|
+
if (this._compacting === v)
|
|
15644
|
+
return;
|
|
15645
|
+
this._compacting = v;
|
|
15646
|
+
this.emit("compacting", v);
|
|
15647
|
+
}
|
|
15344
15648
|
/** Token and cost totals (`get_session_stats`). */
|
|
15345
15649
|
async stats() {
|
|
15346
15650
|
const raw = await this.call(this.requireAlive(), { type: "get_session_stats" });
|
|
15651
|
+
const cu = raw?.contextUsage;
|
|
15652
|
+
const context = cu && typeof cu.contextWindow === "number" ? {
|
|
15653
|
+
tokens: typeof cu.tokens === "number" ? cu.tokens : null,
|
|
15654
|
+
window: cu.contextWindow,
|
|
15655
|
+
percent: typeof cu.percent === "number" ? cu.percent : null
|
|
15656
|
+
} : null;
|
|
15347
15657
|
return {
|
|
15658
|
+
context,
|
|
15348
15659
|
tokens: typeof raw?.tokens?.total === "number" ? raw.tokens.total : null,
|
|
15349
15660
|
costUsd: typeof raw?.cost === "number" ? raw.cost : null,
|
|
15350
15661
|
raw
|
|
@@ -15478,6 +15789,12 @@ var ManagedSession = class _ManagedSession extends EventEmitter5 {
|
|
|
15478
15789
|
this.emit("bridge", msg);
|
|
15479
15790
|
if (msg.type === "ui_prompt_end")
|
|
15480
15791
|
this.onPromptEnd(msg);
|
|
15792
|
+
if (msg.type === "model_state") {
|
|
15793
|
+
this.applyScoped(msg.scoped);
|
|
15794
|
+
this.applyModel(msg.model);
|
|
15795
|
+
this.applyThinking(msg.thinkingLevel);
|
|
15796
|
+
this.emitModelIfChanged();
|
|
15797
|
+
}
|
|
15481
15798
|
});
|
|
15482
15799
|
proc.on("stderr", (text) => this.emit("stderr", text));
|
|
15483
15800
|
proc.on("protocol_error", (err, line) => {
|
|
@@ -15520,6 +15837,7 @@ var ManagedSession = class _ManagedSession extends EventEmitter5 {
|
|
|
15520
15837
|
this.emit("ui_resolved", { id, by: "exit", request: req });
|
|
15521
15838
|
this.pending.clear();
|
|
15522
15839
|
this.current = null;
|
|
15840
|
+
this.setCompacting(false);
|
|
15523
15841
|
const wasBusy = this.busy;
|
|
15524
15842
|
this.busy = false;
|
|
15525
15843
|
if (this.terminal === "failed") {
|
|
@@ -15686,15 +16004,29 @@ var ManagedSession = class _ManagedSession extends EventEmitter5 {
|
|
|
15686
16004
|
this.notice("error", `Retry failed: ${ev.finalError ?? "unknown error"}`);
|
|
15687
16005
|
break;
|
|
15688
16006
|
case "compaction_start":
|
|
16007
|
+
this.setCompacting(true);
|
|
15689
16008
|
this.notice("info", `Compacting context (${ev.reason ?? "manual"})`);
|
|
15690
16009
|
break;
|
|
15691
16010
|
case "compaction_end":
|
|
16011
|
+
this.setCompacting(false);
|
|
15692
16012
|
if (ev.result)
|
|
15693
16013
|
this.notice("info", "Context compacted");
|
|
15694
16014
|
else if (ev.aborted)
|
|
15695
16015
|
this.notice("warning", "Compaction aborted");
|
|
15696
|
-
else
|
|
15697
|
-
|
|
16016
|
+
else {
|
|
16017
|
+
const msg = String(ev.errorMessage ?? "unknown error").replace(/^Compaction failed:\s*/, "");
|
|
16018
|
+
this.notice("error", `Compaction failed: ${msg}`);
|
|
16019
|
+
}
|
|
16020
|
+
break;
|
|
16021
|
+
case "model_state":
|
|
16022
|
+
this.applyScoped(ev.scoped);
|
|
16023
|
+
this.applyModel(ev.model);
|
|
16024
|
+
this.applyThinking(ev.thinkingLevel);
|
|
16025
|
+
this.emitModelIfChanged();
|
|
16026
|
+
break;
|
|
16027
|
+
case "thinking_level_changed":
|
|
16028
|
+
this.applyThinking(ev.level);
|
|
16029
|
+
this.emitModelIfChanged();
|
|
15698
16030
|
break;
|
|
15699
16031
|
case "extension_error":
|
|
15700
16032
|
this.emit("diagnostic", {
|
|
@@ -15987,6 +16319,7 @@ var SessionSupervisor = class {
|
|
|
15987
16319
|
markLost(rec, expireSummary) {
|
|
15988
16320
|
rec.runtime = "interrupted";
|
|
15989
16321
|
rec.runtimeDetail = "Host agent restarted";
|
|
16322
|
+
rec.compacting = false;
|
|
15990
16323
|
rec.queue = { steering: [], followUp: [] };
|
|
15991
16324
|
rec.terminal = null;
|
|
15992
16325
|
this.expirePending(rec.id, expireSummary);
|
|
@@ -16116,6 +16449,9 @@ var SessionSupervisor = class {
|
|
|
16116
16449
|
archivedAt: null,
|
|
16117
16450
|
queue: rec.queue,
|
|
16118
16451
|
stats: rec.stats,
|
|
16452
|
+
model: rec.model ?? null,
|
|
16453
|
+
thinking: rec.thinking ?? null,
|
|
16454
|
+
compacting: rec.compacting ?? false,
|
|
16119
16455
|
lastAssistantText: rec.lastAssistantText,
|
|
16120
16456
|
createdAt: rec.createdAt,
|
|
16121
16457
|
terminal: rec.terminal != null
|
|
@@ -16241,6 +16577,9 @@ var SessionSupervisor = class {
|
|
|
16241
16577
|
nextOrder,
|
|
16242
16578
|
queue: { steering: [], followUp: [] },
|
|
16243
16579
|
stats: prev?.stats ?? null,
|
|
16580
|
+
model: prev?.model ?? null,
|
|
16581
|
+
thinking: prev?.thinking ?? null,
|
|
16582
|
+
compacting: false,
|
|
16244
16583
|
lastAssistantText: prev?.lastAssistantText ?? null,
|
|
16245
16584
|
lastActivityAt: now,
|
|
16246
16585
|
createdAt: prev?.createdAt ?? now
|
|
@@ -16331,6 +16670,28 @@ var SessionSupervisor = class {
|
|
|
16331
16670
|
this.db.tx(() => this.saveAndEmit(rec));
|
|
16332
16671
|
return { title };
|
|
16333
16672
|
}
|
|
16673
|
+
async models(sessionId) {
|
|
16674
|
+
return { models: await this.requireLive(sessionId).models() };
|
|
16675
|
+
}
|
|
16676
|
+
async commands(sessionId) {
|
|
16677
|
+
return { commands: await this.requireLive(sessionId).commands() };
|
|
16678
|
+
}
|
|
16679
|
+
async setModel(sessionId, provider, modelId) {
|
|
16680
|
+
return this.requireLive(sessionId).setModel(provider, modelId);
|
|
16681
|
+
}
|
|
16682
|
+
async setThinking(sessionId, level) {
|
|
16683
|
+
return this.requireLive(sessionId).setThinking(level);
|
|
16684
|
+
}
|
|
16685
|
+
async compact(sessionId, instructions) {
|
|
16686
|
+
const ms = this.requireLive(sessionId);
|
|
16687
|
+
if (ms.compacting)
|
|
16688
|
+
throw new SwitchyardError("conflict", "Compaction is already running");
|
|
16689
|
+
if (ms.runtime !== "idle") {
|
|
16690
|
+
throw new SwitchyardError("conflict", "Wait for the run to finish before compacting");
|
|
16691
|
+
}
|
|
16692
|
+
await ms.compact(instructions);
|
|
16693
|
+
return { ok: true };
|
|
16694
|
+
}
|
|
16334
16695
|
async adapterAction(sessionId, adapterId, actionId, payload) {
|
|
16335
16696
|
const l = this.live.get(sessionId);
|
|
16336
16697
|
if (!l?.adapters) {
|
|
@@ -16585,6 +16946,18 @@ var SessionSupervisor = class {
|
|
|
16585
16946
|
this.db.tx(() => this.saveAndEmit(rec));
|
|
16586
16947
|
}
|
|
16587
16948
|
});
|
|
16949
|
+
ms.on("model", (m) => {
|
|
16950
|
+
rec.model = m.model;
|
|
16951
|
+
rec.thinking = m.thinking;
|
|
16952
|
+
this.db.tx(() => this.saveAndEmit(rec));
|
|
16953
|
+
void this.refreshStats(l);
|
|
16954
|
+
});
|
|
16955
|
+
ms.on("compacting", (c) => {
|
|
16956
|
+
rec.compacting = c;
|
|
16957
|
+
this.db.tx(() => this.saveAndEmit(rec));
|
|
16958
|
+
if (!c)
|
|
16959
|
+
void this.refreshStats(l);
|
|
16960
|
+
});
|
|
16588
16961
|
ms.on("diagnostic", (d) => this.diagnostic(rec.id, null, d.level, d.message));
|
|
16589
16962
|
ms.on("stderr", (text) => this.opts.log.debug({ sessionId: rec.id, stderr: text.slice(0, 2e3) }, "pi stderr"));
|
|
16590
16963
|
ms.on("ui_request", (req) => this.enqueue(l, () => this.onUiRequest(l, req)));
|
|
@@ -16619,7 +16992,7 @@ var SessionSupervisor = class {
|
|
|
16619
16992
|
return;
|
|
16620
16993
|
try {
|
|
16621
16994
|
const s = await ms.stats();
|
|
16622
|
-
const stats = { tokens: s.tokens, costUsd: s.costUsd };
|
|
16995
|
+
const stats = { tokens: s.tokens, costUsd: s.costUsd, context: s.context };
|
|
16623
16996
|
if (JSON.stringify(stats) === JSON.stringify(l.rec.stats))
|
|
16624
16997
|
return;
|
|
16625
16998
|
l.rec.stats = stats;
|
|
@@ -16664,6 +17037,8 @@ var SessionSupervisor = class {
|
|
|
16664
17037
|
return;
|
|
16665
17038
|
case "message_end": {
|
|
16666
17039
|
const m = ev.message;
|
|
17040
|
+
if (m?.role === "assistant")
|
|
17041
|
+
void this.refreshStats(l);
|
|
16667
17042
|
if (adapters && m?.role === "custom" && typeof m.customType === "string") {
|
|
16668
17043
|
await adapters.onCustomMessage({
|
|
16669
17044
|
customType: m.customType,
|