dsh-synapse 0.5.0 → 0.5.1

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.
Files changed (2) hide show
  1. package/app.js +28 -7
  2. package/package.json +1 -1
package/app.js CHANGED
@@ -1116,16 +1116,35 @@ function threadMessage(thread, message) {
1116
1116
  return `<article class="message message-${message.kind}${message.pending ? ' message-pending' : ''}${collapsible ? ' message-collapsible' : ''}${expanded ? ' expanded' : ''}" data-message-seq="${Number.isInteger(message.sourceSeq) ? message.sourceSeq : ''}"><header>${avatar}<span class="message-role">${label}</span><time>${formatTime(message.at)}</time>${branch}${fold}</header><div class="message-body">${body}</div></article>`
1117
1117
  }
1118
1118
 
1119
+ /**
1120
+ * Stored process entries carry a `status` (`pending` / `done` / `failed`);
1121
+ * records folded in from a v3-era message still carry `error` / `result`. Read
1122
+ * both shapes, otherwise a finished tool renders as a failure only because the
1123
+ * newer shape has no `error` key at all (`undefined !== null`).
1124
+ */
1125
+ function processState(entry) {
1126
+ if (entry.status === 'failed') return 'failed'
1127
+ if (entry.status === 'pending') return 'pending'
1128
+ if (entry.status === 'done') return 'done'
1129
+ if (typeof entry.error === 'string') return entry.error === '' ? (entry.result === null || entry.result === undefined ? 'pending' : 'done') : 'failed'
1130
+ if (entry.error !== null && entry.error !== undefined) return 'failed'
1131
+ return entry.result === null || entry.result === undefined ? 'pending' : 'done'
1132
+ }
1133
+
1119
1134
  function processRecords(process, messageId) {
1120
1135
  const key = `${messageId}:process`
1121
1136
  const expanded = state.expandedMessageIds.has(key)
1122
1137
  const entries = process.map((entry, index) => {
1123
1138
  const entryKey = `${key}:${index}`
1124
1139
  const entryExpanded = state.expandedMessageIds.has(entryKey)
1125
- const status = entry.error !== null ? '失败' : entry.result === null ? '等待结果' : '完成'
1126
- const argumentsHtml = entry.arguments === null || entry.arguments === '' ? '' : `<pre class="process-args">${escapeHtml(entry.arguments)}</pre>`
1127
- const outcomeHtml = entry.error !== null ? `<pre class="process-error">${escapeHtml(entry.error)}</pre>` : entry.result === null ? '' : `<pre class="process-result">${escapeHtml(entry.result)}</pre>`
1128
- return `<div class="process-entry${entryExpanded ? ' expanded' : ''}"><button class="process-entry-fold" data-action="toggle-message" data-message="${escapeHtml(entryKey)}"><span class="process-entry-name">${escapeHtml(entry.name)}</span><span class="process-status${entry.error !== null ? ' process-status-error' : entry.result === null ? ' process-status-pending' : ' process-status-done'}">${status}</span></button>${entryExpanded ? `<div class="process-entry-body">${argumentsHtml}${outcomeHtml}</div>` : ''}</div>`
1140
+ const state_ = processState(entry)
1141
+ const status = state_ === 'failed' ? '失败' : state_ === 'pending' ? '等待结果' : '完成'
1142
+ const statusClass = state_ === 'failed' ? ' process-status-error' : state_ === 'pending' ? ' process-status-pending' : ' process-status-done'
1143
+ const argumentsHtml = typeof entry.arguments === 'string' && entry.arguments !== '' ? `<pre class="process-args">${escapeHtml(entry.arguments)}</pre>` : ''
1144
+ const outcomeHtml = state_ === 'failed' && typeof entry.error === 'string' && entry.error !== ''
1145
+ ? `<pre class="process-error">${escapeHtml(entry.error)}</pre>`
1146
+ : typeof entry.result === 'string' && entry.result !== '' ? `<pre class="process-result">${escapeHtml(entry.result)}</pre>` : ''
1147
+ return `<div class="process-entry${entryExpanded ? ' expanded' : ''}"><button class="process-entry-fold" data-action="toggle-message" data-message="${escapeHtml(entryKey)}"><span class="process-entry-name">${escapeHtml(entry.name)}</span><span class="process-status${statusClass}">${status}</span></button>${entryExpanded ? `<div class="process-entry-body">${argumentsHtml}${outcomeHtml}</div>` : ''}</div>`
1129
1148
  }).join('')
1130
1149
  return `<section class="process-records${expanded ? ' expanded' : ''}"><button class="process-records-fold" data-action="toggle-message" data-message="${escapeHtml(key)}"><span>${expanded ? '收起过程记录' : '过程记录'}</span><span class="process-count">${process.length}</span></button>${expanded ? entries : ''}</section>`
1131
1150
  }
@@ -1157,13 +1176,15 @@ function inspectorProcessEntries(messages) {
1157
1176
  continue
1158
1177
  }
1159
1178
  if (message.kind === 'tool') {
1160
- entries.push({ name: processSummary(message.text), arguments: message.text, result: null, error: null })
1179
+ entries.push({ name: processSummary(message.text), arguments: message.text, status: 'pending' })
1161
1180
  continue
1162
1181
  }
1163
1182
  if (message.kind === 'tool-result') {
1164
1183
  const previous = entries.at(-1)
1165
- if (previous !== undefined && previous.result === null && previous.error === null) previous.result = message.text
1166
- else entries.push({ name: '工具结果', arguments: null, result: message.text, error: null })
1184
+ if (previous !== undefined && processState(previous) === 'pending') {
1185
+ previous.status = 'done'
1186
+ previous.result = message.text
1187
+ } else entries.push({ name: '工具结果', arguments: null, status: 'done', result: message.text })
1167
1188
  }
1168
1189
  }
1169
1190
  return entries
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-synapse",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "A visual, non-linear conversation workspace plugin for DeepSeek Harness.",
5
5
  "type": "module",
6
6
  "main": "index.js",