@nuvin/session 0.1.0-rc.12 → 0.1.0-rc.13

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.
@@ -77,6 +77,7 @@ function createSessionController(deps) {
77
77
  let seq = 0;
78
78
  let approvalMode = "ask";
79
79
  let abortController = null;
80
+ let hostBusyCount = 0;
80
81
  let questionCounter = 0;
81
82
  const listeners = /* @__PURE__ */ new Set();
82
83
  const approvalResolvers = /* @__PURE__ */ new Map();
@@ -107,10 +108,10 @@ function createSessionController(deps) {
107
108
  draining = false;
108
109
  }
109
110
  };
110
- const emitTurnStatus = (busy) => {
111
+ const emitTurnStatus = () => {
111
112
  emit({
112
113
  type: "turn-status",
113
- busy,
114
+ busy: abortController !== null || hostBusyCount > 0,
114
115
  queuedCount: queue.length,
115
116
  queued: queue.map((q) => ({
116
117
  id: q.id,
@@ -124,6 +125,7 @@ function createSessionController(deps) {
124
125
  emit({ type: "agent-event", event, ...scope ? { scope } : {} });
125
126
  });
126
127
  const unsubscribeLoaded = deps.channel.onSessionLoaded((loaded) => {
128
+ queue.length = 0;
127
129
  abortController?.abort(new Error("Session loaded; the active turn was cancelled."));
128
130
  rejectAllPending("Session loaded; pending interactions were cancelled.");
129
131
  emit({
@@ -134,6 +136,7 @@ function createSessionController(deps) {
134
136
  // else a resumed session reverts to the empty seed meta (no model name).
135
137
  state: {
136
138
  ...createSessionViewState(),
139
+ busy: hostBusyCount > 0,
137
140
  meta: state.meta,
138
141
  messages: createMessageStateFromMessages(loaded.messages)
139
142
  }
@@ -222,28 +225,31 @@ function createSessionController(deps) {
222
225
  }
223
226
  questionResolvers.clear();
224
227
  }
228
+ function startNextQueuedSubmission() {
229
+ if (abortController || hostBusyCount > 0) return;
230
+ const next = queue.shift();
231
+ if (!next) return;
232
+ if (!next.opts.silent) {
233
+ emit({
234
+ type: "user-message",
235
+ text: next.opts.displayText,
236
+ ...next.opts.attachmentLabels?.length ? { attachmentLabels: next.opts.attachmentLabels } : {}
237
+ });
238
+ }
239
+ void runTurn(next.input, {});
240
+ }
225
241
  function finalizeTurn(controller, reason) {
226
242
  if (abortController !== controller) return;
227
243
  abortController = null;
228
244
  rejectAllPending(reason);
229
- emitTurnStatus(false);
230
- const next = queue.shift();
231
- if (next) {
232
- if (!next.opts.silent) {
233
- emit({
234
- type: "user-message",
235
- text: next.opts.displayText,
236
- ...next.opts.attachmentLabels?.length ? { attachmentLabels: next.opts.attachmentLabels } : {}
237
- });
238
- }
239
- void runTurn(next.input, {});
240
- }
245
+ emitTurnStatus();
246
+ startNextQueuedSubmission();
241
247
  }
242
248
  async function runTurn(input, opts) {
243
249
  const controller = new AbortController();
244
250
  abortController = controller;
245
251
  try {
246
- emitTurnStatus(true);
252
+ emitTurnStatus();
247
253
  if (!opts.systemInitiated) autoCompactionChain = 0;
248
254
  compaction?.setEnabled(true);
249
255
  let finalInput = input;
@@ -341,7 +347,7 @@ function createSessionController(deps) {
341
347
  const index = queue.findIndex((q) => q.id === queuedId);
342
348
  if (index === -1) return false;
343
349
  queue.splice(index, 1);
344
- emitTurnStatus(abortController !== null);
350
+ emitTurnStatus();
345
351
  return true;
346
352
  },
347
353
  decideApproval(toolCallId, decision, comment, grantDir) {
@@ -389,6 +395,9 @@ function createSessionController(deps) {
389
395
  getSnapshot() {
390
396
  return { seq, state, serverCommands };
391
397
  },
398
+ isHostBusy() {
399
+ return hostBusyCount > 0;
400
+ },
392
401
  onEvent(listener) {
393
402
  listeners.add(listener);
394
403
  return () => listeners.delete(listener);
@@ -413,6 +422,7 @@ function createSessionController(deps) {
413
422
  },
414
423
  reset() {
415
424
  queue.length = 0;
425
+ hostBusyCount = 0;
416
426
  abortController?.abort(new Error("Session reset."));
417
427
  rejectAllPending("Session reset; pending interactions were cancelled.");
418
428
  alwaysApproved.clear();
@@ -425,10 +435,19 @@ function createSessionController(deps) {
425
435
  setApprovalMode(mode) {
426
436
  approvalMode = mode;
427
437
  },
438
+ setBusy(busy) {
439
+ if (busy) {
440
+ hostBusyCount += 1;
441
+ } else if (hostBusyCount > 0) {
442
+ hostBusyCount -= 1;
443
+ }
444
+ emitTurnStatus();
445
+ startNextQueuedSubmission();
446
+ },
428
447
  async submit(input, opts) {
429
- if (abortController) {
448
+ if (abortController || hostBusyCount > 0) {
430
449
  queue.push({ id: `q-${++queueCounter}`, input, opts });
431
- emitTurnStatus(true);
450
+ emitTurnStatus();
432
451
  return;
433
452
  }
434
453
  if (!opts.silent) {
@@ -107,6 +107,8 @@ export interface SessionController {
107
107
  * mutated in place. Callers must treat the returned state as read-only.
108
108
  */
109
109
  getSnapshot(): SessionSnapshot;
110
+ /** Return whether a host-controlled server operation currently owns busy state. */
111
+ isHostBusy(): boolean;
110
112
  onEvent(listener: (event: ServerEvent) => void): () => void;
111
113
  /**
112
114
  * Replace the server-executed slash-command descriptors surfaced in the attach
@@ -147,6 +149,7 @@ export interface SessionController {
147
149
  */
148
150
  reset(): void;
149
151
  setApprovalMode(mode: SessionApprovalMode): void;
152
+ setBusy(busy: boolean): void;
150
153
  /**
151
154
  * Submit user input. If no turn is active, the returned promise resolves
152
155
  * when the turn completes. If a turn is already active, the submission is
@@ -1 +1 @@
1
- {"version":3,"file":"session-controller.d.ts","sourceRoot":"","sources":["../../src/controller/session-controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-controller.d.ts","sourceRoot":"","sources":["../../src/controller/session-controller.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuvin/session",
3
- "version": "0.1.0-rc.12",
3
+ "version": "0.1.0-rc.13",
4
4
  "private": false,
5
5
  "description": "Headless session layer for Nuvin: state reducers, wire protocol, session controller",
6
6
  "license": "Apache-2.0",
@@ -50,7 +50,7 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "ws": "^8.20.0",
53
- "@nuvin/agent-core": "^0.1.0-rc.10"
53
+ "@nuvin/agent-core": "^0.1.0-rc.11"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/node": "^22.0.0",