@mirasoth/soothe-client 0.5.1 → 0.5.2
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/{chunk-R43B23MJ.js → chunk-NSWLUFSA.js} +2 -2
- package/dist/{chunk-R43B23MJ.js.map → chunk-NSWLUFSA.js.map} +1 -1
- package/dist/client-YTWVWNAN.js +7 -0
- package/dist/index.cjs +140 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -9
- package/dist/index.d.ts +33 -9
- package/dist/index.js +133 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/client-SCSBM3EL.js +0 -7
- /package/dist/{client-SCSBM3EL.js.map → client-YTWVWNAN.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -357,7 +357,7 @@ var init_protocol = __esm({
|
|
|
357
357
|
import_node_crypto = require("crypto");
|
|
358
358
|
PROTO_VERSION = "1";
|
|
359
359
|
DEFAULT_CLIENT_CAPABILITIES = ["streaming", "batch", "heartbeat", "receipts"];
|
|
360
|
-
CLIENT_VERSION = "0.5.
|
|
360
|
+
CLIENT_VERSION = "0.5.2";
|
|
361
361
|
}
|
|
362
362
|
});
|
|
363
363
|
|
|
@@ -2069,9 +2069,14 @@ __export(index_exports, {
|
|
|
2069
2069
|
StaleLoopError: () => StaleLoopError,
|
|
2070
2070
|
StreamCloseFail: () => StreamCloseFail,
|
|
2071
2071
|
StreamCloseSoftComplete: () => StreamCloseSoftComplete,
|
|
2072
|
+
TURN_END_IDLE: () => TURN_END_IDLE,
|
|
2073
|
+
TURN_END_STOPPED: () => TURN_END_STOPPED,
|
|
2074
|
+
TURN_END_STREAM_END: () => TURN_END_STREAM_END,
|
|
2072
2075
|
TimeoutError: () => TimeoutError,
|
|
2073
2076
|
TimeoutPolicy: () => TimeoutPolicy,
|
|
2077
|
+
TurnBoundary: () => TurnBoundary,
|
|
2074
2078
|
TurnEventStats: () => TurnEventStats,
|
|
2079
|
+
TurnLifecycleGate: () => TurnLifecycleGate,
|
|
2075
2080
|
TurnRunner: () => TurnRunner,
|
|
2076
2081
|
VerbosityTier: () => VerbosityTier,
|
|
2077
2082
|
authenticate: () => authenticate,
|
|
@@ -2101,6 +2106,7 @@ __export(index_exports, {
|
|
|
2101
2106
|
inputMessageForLoop: () => inputMessageForLoop,
|
|
2102
2107
|
isCompletionEvent: () => isCompletionEvent,
|
|
2103
2108
|
isDaemonLive: () => isDaemonLive,
|
|
2109
|
+
isDaemonTurnEndEvent: () => isDaemonTurnEndEvent,
|
|
2104
2110
|
isSubagentProgressEvent: () => isSubagentProgressEvent,
|
|
2105
2111
|
isTurnEndCustomData: () => isTurnEndCustomData,
|
|
2106
2112
|
isTurnProgressChunk: () => isTurnProgressChunk,
|
|
@@ -2743,6 +2749,8 @@ var EventClassifier = class {
|
|
|
2743
2749
|
if (!eventType) return false;
|
|
2744
2750
|
switch (eventType) {
|
|
2745
2751
|
case "status.idle":
|
|
2752
|
+
case "status.stopped":
|
|
2753
|
+
case "soothe.stream.end":
|
|
2746
2754
|
case "idle_timeout":
|
|
2747
2755
|
case "query_timeout":
|
|
2748
2756
|
case "stream_closed":
|
|
@@ -3453,6 +3461,110 @@ async function compactAttachments(atts, opts) {
|
|
|
3453
3461
|
|
|
3454
3462
|
// src/appkit/turn_runner.ts
|
|
3455
3463
|
init_intent_hints();
|
|
3464
|
+
|
|
3465
|
+
// src/appkit/turn_boundary.ts
|
|
3466
|
+
init_stream_terminal();
|
|
3467
|
+
var TURN_END_STREAM_END = STREAM_END;
|
|
3468
|
+
var TURN_END_IDLE = "status.idle";
|
|
3469
|
+
var TURN_END_STOPPED = "status.stopped";
|
|
3470
|
+
var TurnLifecycleGate = class {
|
|
3471
|
+
sawRunning = false;
|
|
3472
|
+
sawStreamPayload = false;
|
|
3473
|
+
sawTurnProgress = false;
|
|
3474
|
+
observe(msg) {
|
|
3475
|
+
const frame = normalizeFrame(msg);
|
|
3476
|
+
if (!frame) return;
|
|
3477
|
+
const typ = String(frame.type ?? "");
|
|
3478
|
+
if (typ === "status") {
|
|
3479
|
+
if (String(frame.state ?? "").trim().toLowerCase() === "running") {
|
|
3480
|
+
this.sawRunning = true;
|
|
3481
|
+
}
|
|
3482
|
+
return;
|
|
3483
|
+
}
|
|
3484
|
+
if (typ === "event") {
|
|
3485
|
+
this.sawStreamPayload = true;
|
|
3486
|
+
const mode = String(frame.mode ?? "");
|
|
3487
|
+
if (isTurnProgressChunk(mode, frame.data)) {
|
|
3488
|
+
this.sawTurnProgress = true;
|
|
3489
|
+
}
|
|
3490
|
+
}
|
|
3491
|
+
}
|
|
3492
|
+
allowStreamEnd() {
|
|
3493
|
+
return this.sawRunning && this.sawTurnProgress;
|
|
3494
|
+
}
|
|
3495
|
+
allowIdleComplete() {
|
|
3496
|
+
return this.sawRunning && this.sawStreamPayload;
|
|
3497
|
+
}
|
|
3498
|
+
};
|
|
3499
|
+
var TurnBoundary = class {
|
|
3500
|
+
gate = new TurnLifecycleGate();
|
|
3501
|
+
ended = false;
|
|
3502
|
+
reason = "";
|
|
3503
|
+
feed(msg) {
|
|
3504
|
+
if (this.ended) return [true, this.reason];
|
|
3505
|
+
this.gate.observe(msg);
|
|
3506
|
+
const frame = normalizeFrame(msg);
|
|
3507
|
+
if (!frame) return [false, ""];
|
|
3508
|
+
const typ = String(frame.type ?? "");
|
|
3509
|
+
if (typ === "status") {
|
|
3510
|
+
const state = String(frame.state ?? "").trim().toLowerCase();
|
|
3511
|
+
if (state === "stopped" && this.gate.sawRunning) {
|
|
3512
|
+
return this.mark(TURN_END_STOPPED);
|
|
3513
|
+
}
|
|
3514
|
+
if (state === "idle" && this.gate.allowIdleComplete()) {
|
|
3515
|
+
return this.mark(TURN_END_IDLE);
|
|
3516
|
+
}
|
|
3517
|
+
return [false, ""];
|
|
3518
|
+
}
|
|
3519
|
+
if (typ === "event") {
|
|
3520
|
+
const mode = String(frame.mode ?? "");
|
|
3521
|
+
if (mode === "custom" && isTurnEndCustomData(frame.data) && this.gate.allowStreamEnd()) {
|
|
3522
|
+
return this.mark(TURN_END_STREAM_END);
|
|
3523
|
+
}
|
|
3524
|
+
}
|
|
3525
|
+
return [false, ""];
|
|
3526
|
+
}
|
|
3527
|
+
mark(reason) {
|
|
3528
|
+
this.ended = true;
|
|
3529
|
+
this.reason = reason;
|
|
3530
|
+
return [true, reason];
|
|
3531
|
+
}
|
|
3532
|
+
};
|
|
3533
|
+
function isDaemonTurnEndEvent(completionEvent) {
|
|
3534
|
+
const e = (completionEvent ?? "").trim();
|
|
3535
|
+
return e === TURN_END_STREAM_END || e === TURN_END_IDLE || e === TURN_END_STOPPED;
|
|
3536
|
+
}
|
|
3537
|
+
function normalizeFrame(msg) {
|
|
3538
|
+
if (!msg || typeof msg !== "object") return null;
|
|
3539
|
+
const m = msg;
|
|
3540
|
+
if (m.type === "next") {
|
|
3541
|
+
const payload = m.payload ?? {};
|
|
3542
|
+
const inner = payload.data;
|
|
3543
|
+
if (inner && typeof inner === "object" && inner.type === "status") {
|
|
3544
|
+
return inner;
|
|
3545
|
+
}
|
|
3546
|
+
if (inner && typeof inner === "object" && inner.mode) {
|
|
3547
|
+
return {
|
|
3548
|
+
type: "event",
|
|
3549
|
+
mode: inner.mode,
|
|
3550
|
+
data: inner.data,
|
|
3551
|
+
namespace: inner.namespace ?? payload.namespace
|
|
3552
|
+
};
|
|
3553
|
+
}
|
|
3554
|
+
if (payload.mode) {
|
|
3555
|
+
return {
|
|
3556
|
+
type: "event",
|
|
3557
|
+
mode: payload.mode,
|
|
3558
|
+
data: payload.data,
|
|
3559
|
+
namespace: payload.namespace
|
|
3560
|
+
};
|
|
3561
|
+
}
|
|
3562
|
+
return null;
|
|
3563
|
+
}
|
|
3564
|
+
return m;
|
|
3565
|
+
}
|
|
3566
|
+
|
|
3567
|
+
// src/appkit/turn_runner.ts
|
|
3456
3568
|
var ErrQueryTimeout = class extends Error {
|
|
3457
3569
|
constructor() {
|
|
3458
3570
|
super("appkit: query timeout");
|
|
@@ -3592,6 +3704,7 @@ var TurnRunner = class {
|
|
|
3592
3704
|
}
|
|
3593
3705
|
let assistantContent = "";
|
|
3594
3706
|
const startedAt = Date.now();
|
|
3707
|
+
const boundary = new TurnBoundary();
|
|
3595
3708
|
const idleForTurn = idleTimeoutForTurn(this.cfg, (attachments?.length ?? 0) > 0);
|
|
3596
3709
|
let idleReject = null;
|
|
3597
3710
|
const armIdle = () => {
|
|
@@ -3684,6 +3797,7 @@ var TurnRunner = class {
|
|
|
3684
3797
|
}
|
|
3685
3798
|
idleRace = armIdle();
|
|
3686
3799
|
const msg = res.value;
|
|
3800
|
+
const [ended, endReason] = boundary.feed(msg);
|
|
3687
3801
|
const eventResult = this.classifier.classify(msg, assistantContent);
|
|
3688
3802
|
if (eventResult.err && eventResult.terminal === 2 /* FailedComplete */) {
|
|
3689
3803
|
clearIdle();
|
|
@@ -3705,7 +3819,7 @@ var TurnRunner = class {
|
|
|
3705
3819
|
eventResult,
|
|
3706
3820
|
assistantContent
|
|
3707
3821
|
);
|
|
3708
|
-
if (deliverable) {
|
|
3822
|
+
if (deliverable && !isDaemonTurnEndEvent(eventResult.completionEvent ?? "")) {
|
|
3709
3823
|
clearIdle();
|
|
3710
3824
|
await this.completeTurn(
|
|
3711
3825
|
sessionID,
|
|
@@ -3716,6 +3830,24 @@ var TurnRunner = class {
|
|
|
3716
3830
|
);
|
|
3717
3831
|
return;
|
|
3718
3832
|
}
|
|
3833
|
+
if (ended) {
|
|
3834
|
+
clearIdle();
|
|
3835
|
+
if (this.classifier.isSubstantiveAssistantReply(assistantContent)) {
|
|
3836
|
+
await this.completeTurn(
|
|
3837
|
+
sessionID,
|
|
3838
|
+
loopID,
|
|
3839
|
+
assistantContent.trim(),
|
|
3840
|
+
startedAt,
|
|
3841
|
+
endReason
|
|
3842
|
+
);
|
|
3843
|
+
return;
|
|
3844
|
+
}
|
|
3845
|
+
const err = new Error(`turn ended (${endReason}) with no assistant content`);
|
|
3846
|
+
await this.persistFailed(sessionID, loopID, err);
|
|
3847
|
+
this.broadcastError(sessionID, err);
|
|
3848
|
+
this.onError?.(sessionID, loopID, err);
|
|
3849
|
+
throw err;
|
|
3850
|
+
}
|
|
3719
3851
|
}
|
|
3720
3852
|
} finally {
|
|
3721
3853
|
clearIdle();
|
|
@@ -4309,9 +4441,14 @@ var DaemonSession = class {
|
|
|
4309
4441
|
StaleLoopError,
|
|
4310
4442
|
StreamCloseFail,
|
|
4311
4443
|
StreamCloseSoftComplete,
|
|
4444
|
+
TURN_END_IDLE,
|
|
4445
|
+
TURN_END_STOPPED,
|
|
4446
|
+
TURN_END_STREAM_END,
|
|
4312
4447
|
TimeoutError,
|
|
4313
4448
|
TimeoutPolicy,
|
|
4449
|
+
TurnBoundary,
|
|
4314
4450
|
TurnEventStats,
|
|
4451
|
+
TurnLifecycleGate,
|
|
4315
4452
|
TurnRunner,
|
|
4316
4453
|
VerbosityTier,
|
|
4317
4454
|
authenticate,
|
|
@@ -4341,6 +4478,7 @@ var DaemonSession = class {
|
|
|
4341
4478
|
inputMessageForLoop,
|
|
4342
4479
|
isCompletionEvent,
|
|
4343
4480
|
isDaemonLive,
|
|
4481
|
+
isDaemonTurnEndEvent,
|
|
4344
4482
|
isSubagentProgressEvent,
|
|
4345
4483
|
isTurnEndCustomData,
|
|
4346
4484
|
isTurnProgressChunk,
|