@treeseed/dsh-chapters 0.2.9 → 0.2.11
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/lib/client.js +51 -12
- package/lib/client.js.map +1 -1
- package/lib/commands.js +55 -0
- package/lib/commands.js.map +1 -1
- package/lib/index.js +36 -1
- package/lib/index.js.map +1 -1
- package/lib/prompt.d.ts +9 -0
- package/lib/prompt.js.map +1 -1
- package/lib/tools.js +31 -5
- package/lib/tools.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -184,11 +184,12 @@ window.__ModuleLoader__.load({
|
|
|
184
184
|
const ACTIVE_POLL_MS = 1e4;
|
|
185
185
|
const QUIET_POLL_MS = 6e4;
|
|
186
186
|
function pollSpacingFor(s) {
|
|
187
|
+
if (s.turnEndPulse === true) return ACTIVE_POLL_MS;
|
|
187
188
|
if (s.edges) {
|
|
188
189
|
if (s.status === "analyzing" || s.autorun === "armed") return ACTIVE_POLL_MS;
|
|
189
190
|
return null;
|
|
190
191
|
}
|
|
191
|
-
const active = s.status === "analyzing" || s.autorun === "armed"
|
|
192
|
+
const active = s.status === "analyzing" || s.autorun === "armed";
|
|
192
193
|
if (!active && s.hidden) return null;
|
|
193
194
|
return active ? ACTIVE_POLL_MS : QUIET_POLL_MS;
|
|
194
195
|
}
|
|
@@ -392,6 +393,26 @@ window.__ModuleLoader__.load({
|
|
|
392
393
|
function edgeKickDelayMs(msSinceLastPull) {
|
|
393
394
|
return Math.max(EDGE_DEBOUNCE_MS, EDGE_FLOOR_MS - msSinceLastPull);
|
|
394
395
|
}
|
|
396
|
+
/**
|
|
397
|
+
* #221: the turn-end pulse, derived from the host's own turn-boundary projection — no plugin
|
|
398
|
+
* record API needed, so it works on 0.2.0 hosts (where appendPluginRecord is absent) exactly as
|
|
399
|
+
* on newer ones. The host maintains a `turnBoundary` projection (the agent loop reads its
|
|
400
|
+
* lastTurn for its own bookkeeping); reading what the host already folds costs zero writes and
|
|
401
|
+
* delivers reactively through the same standard useProjection seat as any other projection.
|
|
402
|
+
* Returns true when a NEW turn ended since the last observation; the dock calls it once per
|
|
403
|
+
* render and stores the returned stamp back into `seen`.
|
|
404
|
+
*/
|
|
405
|
+
function turnEndPulse(lastTurn, seen) {
|
|
406
|
+
const cur = typeof lastTurn === "number" && Number.isFinite(lastTurn) ? lastTurn : 0;
|
|
407
|
+
if (cur > seen) return {
|
|
408
|
+
pulse: true,
|
|
409
|
+
seen: cur
|
|
410
|
+
};
|
|
411
|
+
return {
|
|
412
|
+
pulse: false,
|
|
413
|
+
seen
|
|
414
|
+
};
|
|
415
|
+
}
|
|
395
416
|
// src/client/prompt-dock.ts
|
|
396
417
|
/**
|
|
397
418
|
* The Suggested Next Step dock row (#113) — thin by design.
|
|
@@ -519,7 +540,9 @@ window.__ModuleLoader__.load({
|
|
|
519
540
|
const { sessionId, inputActions, exec } = props;
|
|
520
541
|
const sessionSnapshot = (props.useSession ?? (() => void 0))((snapshot) => snapshot);
|
|
521
542
|
const running = props.running ?? deriveRunning(sessionSnapshot);
|
|
522
|
-
const
|
|
543
|
+
const useProjectionHook = props.useProjection ?? (() => void 0);
|
|
544
|
+
const pushed = useProjectionHook(PROMPT_PROJECTION_KEY);
|
|
545
|
+
const turnBoundary = useProjectionHook("turnBoundary");
|
|
523
546
|
const [state, dispatch] = (0, react.useReducer)(promptBarReducer, initialBarState(), (s) => {
|
|
524
547
|
const pushEvs = pushEventsOf(pushed);
|
|
525
548
|
if (pushEvs !== null) return {
|
|
@@ -544,6 +567,7 @@ window.__ModuleLoader__.load({
|
|
|
544
567
|
const lastPullAt = (0, react.useRef)(null);
|
|
545
568
|
const edgeTimer = (0, react.useRef)(void 0);
|
|
546
569
|
const pushLiveRef = (0, react.useRef)(false);
|
|
570
|
+
const seenTurnRef = (0, react.useRef)(0);
|
|
547
571
|
const lastPushAt = (0, react.useRef)(null);
|
|
548
572
|
const answered = (0, react.useRef)(false);
|
|
549
573
|
const replyStatus = (0, react.useRef)("unknown");
|
|
@@ -605,13 +629,18 @@ window.__ModuleLoader__.load({
|
|
|
605
629
|
pulled.current = true;
|
|
606
630
|
let timer;
|
|
607
631
|
const effectiveStatus = () => replyStatus.current === "unknown" ? stateRef.current.status : replyStatus.current;
|
|
608
|
-
const spacingNow = () =>
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
632
|
+
const spacingNow = () => {
|
|
633
|
+
const pe = turnEndPulse(turnBoundary?.lastTurn, seenTurnRef.current);
|
|
634
|
+
if (pe.pulse) seenTurnRef.current = pe.seen;
|
|
635
|
+
return pollSpacingFor({
|
|
636
|
+
status: effectiveStatus(),
|
|
637
|
+
autorun: stateRef.current.autorun,
|
|
638
|
+
running: stateRef.current.running,
|
|
639
|
+
hidden: typeof document !== "undefined" && document.hidden === true,
|
|
640
|
+
edges: edgesRef.current,
|
|
641
|
+
turnEndPulse: pe.pulse
|
|
642
|
+
});
|
|
643
|
+
};
|
|
615
644
|
const duePull = () => {
|
|
616
645
|
const c = sessionId !== void 0 ? stateCache.get(sessionId) : void 0;
|
|
617
646
|
return mountPullDecision({
|
|
@@ -997,13 +1026,14 @@ window.__ModuleLoader__.load({
|
|
|
997
1026
|
return tryClick();
|
|
998
1027
|
}
|
|
999
1028
|
function makeDoorRunner(remote, sessions, door, verifySwitched, opts) {
|
|
1000
|
-
return async function run(sessionId) {
|
|
1029
|
+
return async function run(sessionId, anchorSeq) {
|
|
1001
1030
|
try {
|
|
1002
1031
|
if (remote.commands?.execute === void 0) return {
|
|
1003
1032
|
ok: false,
|
|
1004
1033
|
message: "commands remote unavailable"
|
|
1005
1034
|
};
|
|
1006
|
-
const
|
|
1035
|
+
const line = typeof anchorSeq === "number" && Number.isFinite(anchorSeq) ? `${door.command} ${String(Math.trunc(anchorSeq))}` : door.command;
|
|
1036
|
+
const res = await remote.commands.execute(sessionId, line, []);
|
|
1007
1037
|
if (res.ok !== true) return {
|
|
1008
1038
|
ok: false,
|
|
1009
1039
|
message: (res.error?.message ?? `the ${door.noun} call failed`).slice(0, 90)
|
|
@@ -1246,7 +1276,16 @@ window.__ModuleLoader__.load({
|
|
|
1246
1276
|
name: "conversation.chat.assistant-actions",
|
|
1247
1277
|
id: door.id,
|
|
1248
1278
|
label: door.label,
|
|
1249
|
-
inject: (sessionId) => ({ run: () =>
|
|
1279
|
+
inject: (sessionId, owner) => ({ run: async () => {
|
|
1280
|
+
let anchor = null;
|
|
1281
|
+
const mid = typeof owner?.messageId === "string" ? owner.messageId : "";
|
|
1282
|
+
if (mid !== "") try {
|
|
1283
|
+
const out = await runCommandText(remote, sessionId, `/chapters-anchor ${mid}`);
|
|
1284
|
+
const n = Number.parseInt(out.trim(), 10);
|
|
1285
|
+
if (Number.isFinite(n) && n > 0) anchor = n;
|
|
1286
|
+
} catch {}
|
|
1287
|
+
return run(sessionId, anchor);
|
|
1288
|
+
} })
|
|
1250
1289
|
}, component));
|
|
1251
1290
|
console.info(`[client:chapters] door factory ran: ${String(effects.length)} register effect(s), types: ${effects.map((e) => typeof e).join(",")}`);
|
|
1252
1291
|
return effects;
|