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 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.5.tgz
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.5.tgz
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
- const stream = api.followSession({ accountId, machineId, sessionId: session.id, cwd: session.cwd });
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() {
@@ -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
- const stream = api.followSession({ accountId, machineId, sessionId: session.id, cwd: session.cwd });
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-monkeyai-sessions",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "在 DeepSeek Harness 中读取和继续 MonkeyAI 会话:查看完整对话历史、下发新指令,无缝接续之前在 MonkeyAI 客户端上的工作",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -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
- const stream = api.followSession({ accountId, machineId, sessionId: session.id, cwd: session.cwd })
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' && ['running', 'idle', 'error', 'interrupted'].includes(status)) {
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)