dsh-monkeyai-sessions 0.1.5 → 0.1.7
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 +1 -1
- package/README.zh.md +1 -1
- package/client.js +4 -3
- package/lib/client-runtime.cjs +4 -3
- package/package.json +1 -1
- package/src/client/index.js +4 -3
- package/src/host/monkeyai-remote.js +20 -2
package/README.md
CHANGED
|
@@ -61,7 +61,7 @@ From a checkout:
|
|
|
61
61
|
npm install
|
|
62
62
|
npm run build
|
|
63
63
|
npm pack
|
|
64
|
-
dsh plugin --profile web add ./dsh-monkeyai-sessions-0.1.
|
|
64
|
+
dsh plugin --profile web add ./dsh-monkeyai-sessions-0.1.7.tgz
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
Verified against a real DSH `0.2.2-rc.1` web profile and a live MonkeyAI runtime: authorization, full history loading, prompt delivery, model switching, and turn cancellation all work end to end.
|
package/README.zh.md
CHANGED
|
@@ -28,7 +28,7 @@ https://artenx.github.io/dsh-monkeyai-sessions/index.json
|
|
|
28
28
|
npm install
|
|
29
29
|
npm run build
|
|
30
30
|
npm pack
|
|
31
|
-
dsh plugin --profile web add ./dsh-monkeyai-sessions-0.1.
|
|
31
|
+
dsh plugin --profile web add ./dsh-monkeyai-sessions-0.1.7.tgz
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
已在真实的 DSH `0.2.2-rc.1` web profile 与在线 MonkeyAI runtime 上端到端验证:授权、完整历史加载、指令下发、模型切换、回合取消均正常工作。
|
package/client.js
CHANGED
|
@@ -1068,8 +1068,9 @@ window.__ModuleLoader__.load({
|
|
|
1068
1068
|
setVisibleCount(RECENT_LIMIT);
|
|
1069
1069
|
setHistoryLoading(true);
|
|
1070
1070
|
setStatus("\u6B63\u5728\u8FDE\u63A5\u8FDC\u7A0B\u4F1A\u8BDD");
|
|
1071
|
+
let stream;
|
|
1071
1072
|
try {
|
|
1072
|
-
|
|
1073
|
+
stream = api.followSession({ accountId, machineId, sessionId: session.id, cwd: session.cwd });
|
|
1073
1074
|
streamRef.current = stream;
|
|
1074
1075
|
setStatus("\u8FDC\u7A0B\u4F1A\u8BDD\u5DF2\u8FDE\u63A5");
|
|
1075
1076
|
for await (const frame of stream) {
|
|
@@ -1139,18 +1140,18 @@ window.__ModuleLoader__.load({
|
|
|
1139
1140
|
}
|
|
1140
1141
|
if (frame.type === "error") setError(frame.message || frame.code || "\u8FDC\u7A0B\u4F1A\u8BDD\u9519\u8BEF");
|
|
1141
1142
|
}
|
|
1143
|
+
if (streamRef.current !== stream) return;
|
|
1142
1144
|
setStatus("\u8FDC\u7A0B\u4F1A\u8BDD\u5DF2\u65AD\u5F00");
|
|
1143
1145
|
setHistoryLoading(false);
|
|
1144
1146
|
setTurnActive(false);
|
|
1145
1147
|
setStopping(false);
|
|
1146
|
-
setSessionStatus("");
|
|
1147
1148
|
} catch (reason) {
|
|
1149
|
+
if (stream && streamRef.current !== stream) return;
|
|
1148
1150
|
setStatus("\u8FDC\u7A0B\u4F1A\u8BDD\u4E0D\u53EF\u7528");
|
|
1149
1151
|
setError(errorText(reason));
|
|
1150
1152
|
setHistoryLoading(false);
|
|
1151
1153
|
setTurnActive(false);
|
|
1152
1154
|
setStopping(false);
|
|
1153
|
-
setSessionStatus("");
|
|
1154
1155
|
}
|
|
1155
1156
|
}
|
|
1156
1157
|
function sendPrompt() {
|
package/lib/client-runtime.cjs
CHANGED
|
@@ -1063,8 +1063,9 @@ function RemoteSessionPage({ api }) {
|
|
|
1063
1063
|
setVisibleCount(RECENT_LIMIT);
|
|
1064
1064
|
setHistoryLoading(true);
|
|
1065
1065
|
setStatus("\u6B63\u5728\u8FDE\u63A5\u8FDC\u7A0B\u4F1A\u8BDD");
|
|
1066
|
+
let stream;
|
|
1066
1067
|
try {
|
|
1067
|
-
|
|
1068
|
+
stream = api.followSession({ accountId, machineId, sessionId: session.id, cwd: session.cwd });
|
|
1068
1069
|
streamRef.current = stream;
|
|
1069
1070
|
setStatus("\u8FDC\u7A0B\u4F1A\u8BDD\u5DF2\u8FDE\u63A5");
|
|
1070
1071
|
for await (const frame of stream) {
|
|
@@ -1134,18 +1135,18 @@ function RemoteSessionPage({ api }) {
|
|
|
1134
1135
|
}
|
|
1135
1136
|
if (frame.type === "error") setError(frame.message || frame.code || "\u8FDC\u7A0B\u4F1A\u8BDD\u9519\u8BEF");
|
|
1136
1137
|
}
|
|
1138
|
+
if (streamRef.current !== stream) return;
|
|
1137
1139
|
setStatus("\u8FDC\u7A0B\u4F1A\u8BDD\u5DF2\u65AD\u5F00");
|
|
1138
1140
|
setHistoryLoading(false);
|
|
1139
1141
|
setTurnActive(false);
|
|
1140
1142
|
setStopping(false);
|
|
1141
|
-
setSessionStatus("");
|
|
1142
1143
|
} catch (reason) {
|
|
1144
|
+
if (stream && streamRef.current !== stream) return;
|
|
1143
1145
|
setStatus("\u8FDC\u7A0B\u4F1A\u8BDD\u4E0D\u53EF\u7528");
|
|
1144
1146
|
setError(errorText(reason));
|
|
1145
1147
|
setHistoryLoading(false);
|
|
1146
1148
|
setTurnActive(false);
|
|
1147
1149
|
setStopping(false);
|
|
1148
|
-
setSessionStatus("");
|
|
1149
1150
|
}
|
|
1150
1151
|
}
|
|
1151
1152
|
function sendPrompt() {
|
package/package.json
CHANGED
package/src/client/index.js
CHANGED
|
@@ -548,8 +548,9 @@ function RemoteSessionPage({ api }) {
|
|
|
548
548
|
setVisibleCount(RECENT_LIMIT)
|
|
549
549
|
setHistoryLoading(true)
|
|
550
550
|
setStatus('正在连接远程会话')
|
|
551
|
+
let stream
|
|
551
552
|
try {
|
|
552
|
-
|
|
553
|
+
stream = api.followSession({ accountId, machineId, sessionId: session.id, cwd: session.cwd })
|
|
553
554
|
streamRef.current = stream
|
|
554
555
|
setStatus('远程会话已连接')
|
|
555
556
|
for await (const frame of stream) {
|
|
@@ -619,18 +620,18 @@ function RemoteSessionPage({ api }) {
|
|
|
619
620
|
}
|
|
620
621
|
if (frame.type === 'error') setError(frame.message || frame.code || '远程会话错误')
|
|
621
622
|
}
|
|
623
|
+
if (streamRef.current !== stream) return
|
|
622
624
|
setStatus('远程会话已断开')
|
|
623
625
|
setHistoryLoading(false)
|
|
624
626
|
setTurnActive(false)
|
|
625
627
|
setStopping(false)
|
|
626
|
-
setSessionStatus('')
|
|
627
628
|
} catch (reason) {
|
|
629
|
+
if (stream && streamRef.current !== stream) return
|
|
628
630
|
setStatus('远程会话不可用')
|
|
629
631
|
setError(errorText(reason))
|
|
630
632
|
setHistoryLoading(false)
|
|
631
633
|
setTurnActive(false)
|
|
632
634
|
setStopping(false)
|
|
633
|
-
setSessionStatus('')
|
|
634
635
|
}
|
|
635
636
|
}
|
|
636
637
|
|
|
@@ -974,11 +974,14 @@ export class MonkeyAIRemoteService extends TypertRemoteService {
|
|
|
974
974
|
}
|
|
975
975
|
// The desktop client tracks turn state via _monkeyai/session/state
|
|
976
976
|
// notifications. Seed the panel with the current status so a turn
|
|
977
|
-
// already running when the panel opens is shown as 进行中.
|
|
977
|
+
// already running when the panel opens is shown as 进行中. The state
|
|
978
|
+
// read omits state.status on some runtime builds, so fall back to the
|
|
979
|
+
// session.status field returned by the history read channel.
|
|
980
|
+
const KNOWN_STATUSES = ['running', 'idle', 'error', 'interrupted']
|
|
978
981
|
try {
|
|
979
982
|
const state = await readSessionState({ httpBase: ticketHttpBase, ticket: ticketValue, sessionId: selectedSession, signal })
|
|
980
983
|
const status = state?.state?.status
|
|
981
|
-
if (typeof status === 'string' &&
|
|
984
|
+
if (typeof status === 'string' && KNOWN_STATUSES.includes(status)) {
|
|
982
985
|
emit({
|
|
983
986
|
type: 'notification',
|
|
984
987
|
sessionId: selectedSession,
|
|
@@ -990,6 +993,21 @@ export class MonkeyAIRemoteService extends TypertRemoteService {
|
|
|
990
993
|
// Older runtimes may not expose the state read; live notifications
|
|
991
994
|
// still drive the status once the next turn starts.
|
|
992
995
|
}
|
|
996
|
+
try {
|
|
997
|
+
const latest = await readSessionHistoryPage({ httpBase: ticketHttpBase, ticket: ticketValue, sessionId: selectedSession, limit: 1, signal })
|
|
998
|
+
const status = latest.session?.status
|
|
999
|
+
if (typeof status === 'string' && KNOWN_STATUSES.includes(status)) {
|
|
1000
|
+
emit({
|
|
1001
|
+
type: 'notification',
|
|
1002
|
+
sessionId: selectedSession,
|
|
1003
|
+
method: '_monkeyai/session/state',
|
|
1004
|
+
data: { sessionId: selectedSession, state: { status } },
|
|
1005
|
+
})
|
|
1006
|
+
}
|
|
1007
|
+
} catch {
|
|
1008
|
+
// The history channel may be unavailable; live notifications remain
|
|
1009
|
+
// the source of truth for subsequent turns.
|
|
1010
|
+
}
|
|
993
1011
|
} catch (error) {
|
|
994
1012
|
if (signal?.aborted) throw error
|
|
995
1013
|
const message = error instanceof Error ? error.message : String(error)
|