dsh-monkeyai-sessions 0.1.4 → 0.1.6
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 +5 -3
- package/lib/client-runtime.cjs +5 -3
- package/package.json +1 -1
- package/src/client/index.js +5 -3
- package/src/host/monkeyai-remote.js +17 -17
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.6.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.6.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) {
|
|
@@ -1080,6 +1081,7 @@ window.__ModuleLoader__.load({
|
|
|
1080
1081
|
historyLoadedRef.current = true;
|
|
1081
1082
|
setStatus("\u5386\u53F2\u5DF2\u52A0\u8F7D");
|
|
1082
1083
|
setHistoryLoading(false);
|
|
1084
|
+
setSessionStatus((current) => current || "idle");
|
|
1083
1085
|
if (frame.model) setCurrentModel(frame.model);
|
|
1084
1086
|
}
|
|
1085
1087
|
if (frame.type === "history_incomplete") {
|
|
@@ -1138,18 +1140,18 @@ window.__ModuleLoader__.load({
|
|
|
1138
1140
|
}
|
|
1139
1141
|
if (frame.type === "error") setError(frame.message || frame.code || "\u8FDC\u7A0B\u4F1A\u8BDD\u9519\u8BEF");
|
|
1140
1142
|
}
|
|
1143
|
+
if (streamRef.current !== stream) return;
|
|
1141
1144
|
setStatus("\u8FDC\u7A0B\u4F1A\u8BDD\u5DF2\u65AD\u5F00");
|
|
1142
1145
|
setHistoryLoading(false);
|
|
1143
1146
|
setTurnActive(false);
|
|
1144
1147
|
setStopping(false);
|
|
1145
|
-
setSessionStatus("");
|
|
1146
1148
|
} catch (reason) {
|
|
1149
|
+
if (stream && streamRef.current !== stream) return;
|
|
1147
1150
|
setStatus("\u8FDC\u7A0B\u4F1A\u8BDD\u4E0D\u53EF\u7528");
|
|
1148
1151
|
setError(errorText(reason));
|
|
1149
1152
|
setHistoryLoading(false);
|
|
1150
1153
|
setTurnActive(false);
|
|
1151
1154
|
setStopping(false);
|
|
1152
|
-
setSessionStatus("");
|
|
1153
1155
|
}
|
|
1154
1156
|
}
|
|
1155
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) {
|
|
@@ -1075,6 +1076,7 @@ function RemoteSessionPage({ api }) {
|
|
|
1075
1076
|
historyLoadedRef.current = true;
|
|
1076
1077
|
setStatus("\u5386\u53F2\u5DF2\u52A0\u8F7D");
|
|
1077
1078
|
setHistoryLoading(false);
|
|
1079
|
+
setSessionStatus((current) => current || "idle");
|
|
1078
1080
|
if (frame.model) setCurrentModel(frame.model);
|
|
1079
1081
|
}
|
|
1080
1082
|
if (frame.type === "history_incomplete") {
|
|
@@ -1133,18 +1135,18 @@ function RemoteSessionPage({ api }) {
|
|
|
1133
1135
|
}
|
|
1134
1136
|
if (frame.type === "error") setError(frame.message || frame.code || "\u8FDC\u7A0B\u4F1A\u8BDD\u9519\u8BEF");
|
|
1135
1137
|
}
|
|
1138
|
+
if (streamRef.current !== stream) return;
|
|
1136
1139
|
setStatus("\u8FDC\u7A0B\u4F1A\u8BDD\u5DF2\u65AD\u5F00");
|
|
1137
1140
|
setHistoryLoading(false);
|
|
1138
1141
|
setTurnActive(false);
|
|
1139
1142
|
setStopping(false);
|
|
1140
|
-
setSessionStatus("");
|
|
1141
1143
|
} catch (reason) {
|
|
1144
|
+
if (stream && streamRef.current !== stream) return;
|
|
1142
1145
|
setStatus("\u8FDC\u7A0B\u4F1A\u8BDD\u4E0D\u53EF\u7528");
|
|
1143
1146
|
setError(errorText(reason));
|
|
1144
1147
|
setHistoryLoading(false);
|
|
1145
1148
|
setTurnActive(false);
|
|
1146
1149
|
setStopping(false);
|
|
1147
|
-
setSessionStatus("");
|
|
1148
1150
|
}
|
|
1149
1151
|
}
|
|
1150
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) {
|
|
@@ -560,6 +561,7 @@ function RemoteSessionPage({ api }) {
|
|
|
560
561
|
historyLoadedRef.current = true
|
|
561
562
|
setStatus('历史已加载')
|
|
562
563
|
setHistoryLoading(false)
|
|
564
|
+
setSessionStatus(current => current || 'idle')
|
|
563
565
|
if (frame.model) setCurrentModel(frame.model)
|
|
564
566
|
}
|
|
565
567
|
if (frame.type === 'history_incomplete') {
|
|
@@ -618,18 +620,18 @@ function RemoteSessionPage({ api }) {
|
|
|
618
620
|
}
|
|
619
621
|
if (frame.type === 'error') setError(frame.message || frame.code || '远程会话错误')
|
|
620
622
|
}
|
|
623
|
+
if (streamRef.current !== stream) return
|
|
621
624
|
setStatus('远程会话已断开')
|
|
622
625
|
setHistoryLoading(false)
|
|
623
626
|
setTurnActive(false)
|
|
624
627
|
setStopping(false)
|
|
625
|
-
setSessionStatus('')
|
|
626
628
|
} catch (reason) {
|
|
629
|
+
if (stream && streamRef.current !== stream) return
|
|
627
630
|
setStatus('远程会话不可用')
|
|
628
631
|
setError(errorText(reason))
|
|
629
632
|
setHistoryLoading(false)
|
|
630
633
|
setTurnActive(false)
|
|
631
634
|
setStopping(false)
|
|
632
|
-
setSessionStatus('')
|
|
633
635
|
}
|
|
634
636
|
}
|
|
635
637
|
|
|
@@ -971,24 +971,24 @@ export class MonkeyAIRemoteService extends TypertRemoteService {
|
|
|
971
971
|
if (httpHistoryComplete) {
|
|
972
972
|
historyRefreshPromise = historyRefreshPromise.then(() => refreshPersistedHistory())
|
|
973
973
|
await historyRefreshPromise
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
} catch {
|
|
989
|
-
// Older runtimes may not expose the state read; live notifications
|
|
990
|
-
// still drive the status once the next turn starts.
|
|
974
|
+
}
|
|
975
|
+
// The desktop client tracks turn state via _monkeyai/session/state
|
|
976
|
+
// notifications. Seed the panel with the current status so a turn
|
|
977
|
+
// already running when the panel opens is shown as 进行中.
|
|
978
|
+
try {
|
|
979
|
+
const state = await readSessionState({ httpBase: ticketHttpBase, ticket: ticketValue, sessionId: selectedSession, signal })
|
|
980
|
+
const status = state?.state?.status
|
|
981
|
+
if (typeof status === 'string' && ['running', 'idle', 'error', 'interrupted'].includes(status)) {
|
|
982
|
+
emit({
|
|
983
|
+
type: 'notification',
|
|
984
|
+
sessionId: selectedSession,
|
|
985
|
+
method: '_monkeyai/session/state',
|
|
986
|
+
data: { sessionId: selectedSession, state: { status }, eventSeq: state.eventSeq },
|
|
987
|
+
})
|
|
991
988
|
}
|
|
989
|
+
} catch {
|
|
990
|
+
// Older runtimes may not expose the state read; live notifications
|
|
991
|
+
// still drive the status once the next turn starts.
|
|
992
992
|
}
|
|
993
993
|
} catch (error) {
|
|
994
994
|
if (signal?.aborted) throw error
|