kernelpm 0.1.11 → 0.1.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.
- package/dist/opencodeDriver.js +28 -2
- package/dist/session.js +6 -0
- package/package.json +1 -1
package/dist/opencodeDriver.js
CHANGED
|
@@ -116,6 +116,16 @@ class ServeOpencodeDriver {
|
|
|
116
116
|
status = 'starting';
|
|
117
117
|
/** Timestamp (ms) of the last `working` emit; null when not working. */
|
|
118
118
|
workingSince = null;
|
|
119
|
+
/**
|
|
120
|
+
* True when no assistant turn is in flight. Arms the next `session.status=
|
|
121
|
+
* busy` handler: opencode's SSE stream occasionally emits a stray `busy`
|
|
122
|
+
* event AFTER the assistant message has already completed (and we've emit
|
|
123
|
+
* `awaiting_input`). Honoring it would flip the status back to `working`
|
|
124
|
+
* right after a finished turn, leaving the app stuck on "escribiendo…"
|
|
125
|
+
* until the watchdog's hard timeout (3 min). We only treat `busy` as
|
|
126
|
+
* genuinely working when the user has armed it by sending a prompt.
|
|
127
|
+
*/
|
|
128
|
+
turnDone = true;
|
|
119
129
|
constructor(sessionId, cwd, title, opts, cb, initial) {
|
|
120
130
|
this.sessionId = sessionId;
|
|
121
131
|
this.cwd = cwd;
|
|
@@ -144,10 +154,12 @@ class ServeOpencodeDriver {
|
|
|
144
154
|
}
|
|
145
155
|
async sendMessage(text) {
|
|
146
156
|
await this.prompt(text);
|
|
157
|
+
this.turnDone = false; // arm: the next `busy` is a legit in-flight turn
|
|
147
158
|
this.emitStatus('working');
|
|
148
159
|
}
|
|
149
160
|
async answer(option) {
|
|
150
161
|
await this.prompt(option.send);
|
|
162
|
+
this.turnDone = false;
|
|
151
163
|
this.emitStatus('working');
|
|
152
164
|
}
|
|
153
165
|
async isAlive() {
|
|
@@ -465,10 +477,20 @@ class ServeOpencodeDriver {
|
|
|
465
477
|
onSessionStatus(p) {
|
|
466
478
|
if (p.sessionID !== this.opencodeId || !p.status)
|
|
467
479
|
return;
|
|
468
|
-
if (p.status.type === 'busy' || p.status.type === 'retry')
|
|
480
|
+
if (p.status.type === 'busy' || p.status.type === 'retry') {
|
|
481
|
+
// Ignore `busy` events that arrive after a turn already completed.
|
|
482
|
+
// opencode's SSE stream occasionally emits a stale busy in the wake of a
|
|
483
|
+
// message.updated with time.completed, and honoring it would flip us
|
|
484
|
+
// back to 'working' right after we just emitted 'awaiting_input',
|
|
485
|
+
// leaving the app stuck on "escribiendo…" until the watchdog's hard
|
|
486
|
+
// timeout. The user's next prompt re-arms `turnDone`.
|
|
487
|
+
if (this.turnDone)
|
|
488
|
+
return;
|
|
469
489
|
this.emitStatus('working');
|
|
470
|
-
|
|
490
|
+
}
|
|
491
|
+
else if (p.status.type === 'idle') {
|
|
471
492
|
this.handleIdle();
|
|
493
|
+
}
|
|
472
494
|
}
|
|
473
495
|
onSessionIdle(p) {
|
|
474
496
|
if (p.sessionID !== this.opencodeId)
|
|
@@ -584,6 +606,10 @@ class ServeOpencodeDriver {
|
|
|
584
606
|
this.emittedTurn.add(messageId);
|
|
585
607
|
this.lastAssistantMessageId = messageId;
|
|
586
608
|
this.lastAssistantText = text;
|
|
609
|
+
// The turn is over: disarm so any subsequent stray `session.status=busy`
|
|
610
|
+
// from opencode's SSE stream doesn't flip us back to 'working' before the
|
|
611
|
+
// user's next prompt.
|
|
612
|
+
this.turnDone = true;
|
|
587
613
|
this.cb.onEvents(events);
|
|
588
614
|
const decision = (0, decisions_1.parseDecision)(text);
|
|
589
615
|
if (decision)
|
package/dist/session.js
CHANGED
|
@@ -27,6 +27,12 @@ class Session {
|
|
|
27
27
|
return this.enqueue(async () => {
|
|
28
28
|
if (this.meta.pendingDecision)
|
|
29
29
|
await this.clearDecision();
|
|
30
|
+
// Persist the user's prompt as a `user_text` event so it round-trips
|
|
31
|
+
// through the store like the assistant's reply: attached clients see it
|
|
32
|
+
// live (via the push fan-out), and a session reopened later replays it
|
|
33
|
+
// from `sessions/<id>.jsonl`. Without this, the daemon only persisted
|
|
34
|
+
// assistant events and resume showed the AI half of the conversation.
|
|
35
|
+
await this.appendBody({ kind: 'user_text', text });
|
|
30
36
|
await this.driver.sendMessage(text);
|
|
31
37
|
});
|
|
32
38
|
}
|
package/package.json
CHANGED