@agent-link/server 0.1.186 → 0.1.188
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/index.js +13 -15
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/web/dist/assets/index-C9bIrYkZ.js +320 -0
- package/web/dist/assets/index-C9bIrYkZ.js.map +1 -0
- package/web/dist/assets/index-Y1FN_mFe.css +1 -0
- package/web/{index.html → dist/index.html} +2 -19
- package/web/app.js +0 -2881
- package/web/css/ask-question.css +0 -333
- package/web/css/base.css +0 -270
- package/web/css/btw.css +0 -148
- package/web/css/chat.css +0 -176
- package/web/css/file-browser.css +0 -499
- package/web/css/input.css +0 -671
- package/web/css/loop.css +0 -674
- package/web/css/markdown.css +0 -169
- package/web/css/responsive.css +0 -314
- package/web/css/sidebar.css +0 -593
- package/web/css/team.css +0 -1277
- package/web/css/tools.css +0 -327
- package/web/encryption.js +0 -56
- package/web/modules/appHelpers.js +0 -100
- package/web/modules/askQuestion.js +0 -63
- package/web/modules/backgroundRouting.js +0 -269
- package/web/modules/connection.js +0 -731
- package/web/modules/fileAttachments.js +0 -125
- package/web/modules/fileBrowser.js +0 -379
- package/web/modules/filePreview.js +0 -213
- package/web/modules/i18n.js +0 -101
- package/web/modules/loop.js +0 -338
- package/web/modules/loopTemplates.js +0 -110
- package/web/modules/markdown.js +0 -83
- package/web/modules/messageHelpers.js +0 -206
- package/web/modules/sidebar.js +0 -402
- package/web/modules/streaming.js +0 -116
- package/web/modules/team.js +0 -396
- package/web/modules/teamTemplates.js +0 -360
- package/web/vendor/highlight.min.js +0 -1213
- package/web/vendor/marked.min.js +0 -6
- package/web/vendor/nacl-fast.min.js +0 -1
- package/web/vendor/nacl-util.min.js +0 -1
- package/web/vendor/pako.min.js +0 -2
- package/web/vendor/vue.global.prod.js +0 -13
- /package/web/{favicon.svg → dist/favicon.svg} +0 -0
- /package/web/{images → dist/images}/chat-iPad.webp +0 -0
- /package/web/{images → dist/images}/chat-iPhone.webp +0 -0
- /package/web/{images → dist/images}/loop-iPad.webp +0 -0
- /package/web/{images → dist/images}/team-iPad.webp +0 -0
- /package/web/{landing.html → dist/landing.html} +0 -0
- /package/web/{landing.zh.html → dist/landing.zh.html} +0 -0
- /package/web/{locales → dist/locales}/en.json +0 -0
- /package/web/{locales → dist/locales}/zh.json +0 -0
- /package/web/{vendor → dist/vendor}/github-dark.min.css +0 -0
- /package/web/{vendor → dist/vendor}/github.min.css +0 -0
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
// ── History batch building & background conversation routing ──────────────────
|
|
2
|
-
import { isContextSummary } from './messageHelpers.js';
|
|
3
|
-
|
|
4
|
-
function findLast(arr, predicate) {
|
|
5
|
-
for (let i = arr.length - 1; i >= 0; i--) {
|
|
6
|
-
if (predicate(arr[i])) return arr[i];
|
|
7
|
-
}
|
|
8
|
-
return undefined;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Convert a history array (from conversation_resumed) into a batch of UI messages.
|
|
13
|
-
* @param {Array} history - Array of {role, content, ...} from the agent
|
|
14
|
-
* @param {() => number} nextId - Function that returns the next message ID
|
|
15
|
-
* @returns {Array} Batch of UI message objects
|
|
16
|
-
*/
|
|
17
|
-
export function buildHistoryBatch(history, nextId) {
|
|
18
|
-
const batch = [];
|
|
19
|
-
for (const h of history) {
|
|
20
|
-
if (h.role === 'user') {
|
|
21
|
-
if (isContextSummary(h.content)) {
|
|
22
|
-
batch.push({
|
|
23
|
-
id: nextId(), role: 'context-summary',
|
|
24
|
-
content: h.content, contextExpanded: false,
|
|
25
|
-
timestamp: h.timestamp ? new Date(h.timestamp) : new Date(),
|
|
26
|
-
});
|
|
27
|
-
} else if (h.isCommandOutput) {
|
|
28
|
-
batch.push({
|
|
29
|
-
id: nextId(), role: 'system',
|
|
30
|
-
content: h.content, isCommandOutput: true,
|
|
31
|
-
timestamp: h.timestamp ? new Date(h.timestamp) : new Date(),
|
|
32
|
-
});
|
|
33
|
-
} else {
|
|
34
|
-
batch.push({
|
|
35
|
-
id: nextId(), role: 'user',
|
|
36
|
-
content: h.content,
|
|
37
|
-
timestamp: h.timestamp ? new Date(h.timestamp) : new Date(),
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
} else if (h.role === 'assistant') {
|
|
41
|
-
const last = batch[batch.length - 1];
|
|
42
|
-
if (last && last.role === 'assistant' && !last.isStreaming) {
|
|
43
|
-
last.content += '\n\n' + h.content;
|
|
44
|
-
} else {
|
|
45
|
-
batch.push({
|
|
46
|
-
id: nextId(), role: 'assistant',
|
|
47
|
-
content: h.content, isStreaming: false,
|
|
48
|
-
timestamp: h.timestamp ? new Date(h.timestamp) : new Date(),
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
} else if (h.role === 'tool') {
|
|
52
|
-
batch.push({
|
|
53
|
-
id: nextId(), role: 'tool',
|
|
54
|
-
toolId: h.toolId || '', toolName: h.toolName || 'unknown',
|
|
55
|
-
toolInput: h.toolInput || '', hasResult: !!h.toolOutput,
|
|
56
|
-
toolOutput: h.toolOutput || '',
|
|
57
|
-
expanded: (h.toolName === 'Edit' || h.toolName === 'TodoWrite' || h.toolName === 'Agent'),
|
|
58
|
-
timestamp: h.timestamp ? new Date(h.timestamp) : new Date(),
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
return batch;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Finalize the last streaming assistant message in a message array.
|
|
67
|
-
* @param {Array} msgs - Array of message objects
|
|
68
|
-
*/
|
|
69
|
-
export function finalizeLastStreaming(msgs) {
|
|
70
|
-
const last = msgs.length > 0 ? msgs[msgs.length - 1] : null;
|
|
71
|
-
if (last && last.role === 'assistant' && last.isStreaming) {
|
|
72
|
-
last.isStreaming = false;
|
|
73
|
-
if (isContextSummary(last.content)) {
|
|
74
|
-
last.role = 'context-summary';
|
|
75
|
-
last.contextExpanded = false;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Route a message to a background (non-foreground) conversation's cache.
|
|
82
|
-
* @param {object} deps - Dependencies: conversationCache, processingConversations, sidebar, wsSend
|
|
83
|
-
* @param {string} convId - The conversation ID
|
|
84
|
-
* @param {object} msg - The incoming message
|
|
85
|
-
*/
|
|
86
|
-
export function routeToBackgroundConversation(deps, convId, msg) {
|
|
87
|
-
const { conversationCache, processingConversations, sidebar, wsSend } = deps;
|
|
88
|
-
const cache = conversationCache.value[convId];
|
|
89
|
-
if (!cache) return;
|
|
90
|
-
|
|
91
|
-
if (msg.type === 'session_started') {
|
|
92
|
-
cache.claudeSessionId = msg.claudeSessionId;
|
|
93
|
-
sidebar.requestSessionList();
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (msg.type === 'conversation_resumed') {
|
|
98
|
-
cache.claudeSessionId = msg.claudeSessionId;
|
|
99
|
-
if (msg.history && Array.isArray(msg.history)) {
|
|
100
|
-
const nextId = () => ++cache.messageIdCounter;
|
|
101
|
-
cache.messages = buildHistoryBatch(msg.history, nextId);
|
|
102
|
-
if (cache.toolMsgMap) cache.toolMsgMap.clear();
|
|
103
|
-
}
|
|
104
|
-
cache.loadingHistory = false;
|
|
105
|
-
if (msg.isCompacting) {
|
|
106
|
-
cache.isCompacting = true;
|
|
107
|
-
cache.isProcessing = true;
|
|
108
|
-
processingConversations.value[convId] = true;
|
|
109
|
-
cache.messages.push({
|
|
110
|
-
id: ++cache.messageIdCounter, role: 'system',
|
|
111
|
-
content: 'Context compacting...', isCompactStart: true,
|
|
112
|
-
timestamp: new Date(),
|
|
113
|
-
});
|
|
114
|
-
} else if (msg.isProcessing) {
|
|
115
|
-
cache.isProcessing = true;
|
|
116
|
-
processingConversations.value[convId] = true;
|
|
117
|
-
cache.messages.push({
|
|
118
|
-
id: ++cache.messageIdCounter, role: 'system',
|
|
119
|
-
content: 'Agent is processing...',
|
|
120
|
-
timestamp: new Date(),
|
|
121
|
-
});
|
|
122
|
-
} else {
|
|
123
|
-
cache.messages.push({
|
|
124
|
-
id: ++cache.messageIdCounter, role: 'system',
|
|
125
|
-
content: 'Session restored. You can continue the conversation.',
|
|
126
|
-
timestamp: new Date(),
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (msg.type === 'claude_output') {
|
|
133
|
-
if (!cache.isProcessing) {
|
|
134
|
-
cache.isProcessing = true;
|
|
135
|
-
processingConversations.value[convId] = true;
|
|
136
|
-
}
|
|
137
|
-
const data = msg.data;
|
|
138
|
-
if (!data) return;
|
|
139
|
-
if (data.type === 'content_block_delta' && data.delta) {
|
|
140
|
-
const msgs = cache.messages;
|
|
141
|
-
const last = msgs.length > 0 ? msgs[msgs.length - 1] : null;
|
|
142
|
-
if (last && last.role === 'assistant' && last.isStreaming) {
|
|
143
|
-
if (!last._chunks) last._chunks = [last.content];
|
|
144
|
-
last._chunks.push(data.delta);
|
|
145
|
-
last.content = last._chunks.join('');
|
|
146
|
-
} else {
|
|
147
|
-
msgs.push({
|
|
148
|
-
id: ++cache.messageIdCounter, role: 'assistant',
|
|
149
|
-
content: data.delta, isStreaming: true, timestamp: new Date(),
|
|
150
|
-
_chunks: [data.delta],
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
} else if (data.type === 'tool_use' && data.tools) {
|
|
154
|
-
const msgs = cache.messages;
|
|
155
|
-
finalizeLastStreaming(msgs);
|
|
156
|
-
for (const tool of data.tools) {
|
|
157
|
-
const toolMsg = {
|
|
158
|
-
id: ++cache.messageIdCounter, role: 'tool',
|
|
159
|
-
toolId: tool.id, toolName: tool.name || 'unknown',
|
|
160
|
-
toolInput: tool.input ? JSON.stringify(tool.input, null, 2) : '',
|
|
161
|
-
hasResult: false, expanded: (tool.name === 'Edit' || tool.name === 'TodoWrite' || tool.name === 'Agent'),
|
|
162
|
-
timestamp: new Date(),
|
|
163
|
-
};
|
|
164
|
-
msgs.push(toolMsg);
|
|
165
|
-
if (tool.id) {
|
|
166
|
-
if (!cache.toolMsgMap) cache.toolMsgMap = new Map();
|
|
167
|
-
cache.toolMsgMap.set(tool.id, toolMsg);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
} else if (data.type === 'user' && data.tool_use_result) {
|
|
171
|
-
const result = data.tool_use_result;
|
|
172
|
-
const results = Array.isArray(result) ? result : [result];
|
|
173
|
-
const tMap = cache.toolMsgMap || new Map();
|
|
174
|
-
for (const r of results) {
|
|
175
|
-
const toolMsg = tMap.get(r.tool_use_id);
|
|
176
|
-
if (toolMsg) {
|
|
177
|
-
toolMsg.toolOutput = typeof r.content === 'string'
|
|
178
|
-
? r.content : JSON.stringify(r.content, null, 2);
|
|
179
|
-
toolMsg.hasResult = true;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
} else if (msg.type === 'turn_completed' || msg.type === 'execution_cancelled') {
|
|
184
|
-
finalizeLastStreaming(cache.messages);
|
|
185
|
-
cache.isProcessing = false;
|
|
186
|
-
cache.isCompacting = false;
|
|
187
|
-
if (msg.usage) cache.usageStats = msg.usage;
|
|
188
|
-
if (cache.toolMsgMap) cache.toolMsgMap.clear();
|
|
189
|
-
processingConversations.value[convId] = false;
|
|
190
|
-
if (msg.type === 'execution_cancelled') {
|
|
191
|
-
cache.needsResume = true;
|
|
192
|
-
cache.messages.push({
|
|
193
|
-
id: ++cache.messageIdCounter, role: 'system',
|
|
194
|
-
content: 'Generation stopped.', timestamp: new Date(),
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
sidebar.requestSessionList();
|
|
198
|
-
if (cache.queuedMessages && cache.queuedMessages.length > 0) {
|
|
199
|
-
const queued = cache.queuedMessages.shift();
|
|
200
|
-
cache.messages.push({
|
|
201
|
-
id: ++cache.messageIdCounter, role: 'user', status: 'sent',
|
|
202
|
-
content: queued.content, attachments: queued.attachments,
|
|
203
|
-
timestamp: new Date(),
|
|
204
|
-
});
|
|
205
|
-
cache.isProcessing = true;
|
|
206
|
-
processingConversations.value[convId] = true;
|
|
207
|
-
wsSend(queued.payload);
|
|
208
|
-
}
|
|
209
|
-
} else if (msg.type === 'context_compaction') {
|
|
210
|
-
if (msg.status === 'started') {
|
|
211
|
-
cache.isCompacting = true;
|
|
212
|
-
cache.messages.push({
|
|
213
|
-
id: ++cache.messageIdCounter, role: 'system',
|
|
214
|
-
content: 'Context compacting...', isCompactStart: true,
|
|
215
|
-
timestamp: new Date(),
|
|
216
|
-
});
|
|
217
|
-
} else if (msg.status === 'completed') {
|
|
218
|
-
cache.isCompacting = false;
|
|
219
|
-
const startMsg = findLast(cache.messages, m => m.isCompactStart && !m.compactDone);
|
|
220
|
-
if (startMsg) {
|
|
221
|
-
startMsg.content = 'Context compacted';
|
|
222
|
-
startMsg.compactDone = true;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
} else if (msg.type === 'error') {
|
|
226
|
-
finalizeLastStreaming(cache.messages);
|
|
227
|
-
cache.messages.push({
|
|
228
|
-
id: ++cache.messageIdCounter, role: 'system',
|
|
229
|
-
content: msg.message, isError: true, timestamp: new Date(),
|
|
230
|
-
});
|
|
231
|
-
cache.isProcessing = false;
|
|
232
|
-
cache.isCompacting = false;
|
|
233
|
-
processingConversations.value[convId] = false;
|
|
234
|
-
} else if (msg.type === 'command_output') {
|
|
235
|
-
finalizeLastStreaming(cache.messages);
|
|
236
|
-
cache.messages.push({
|
|
237
|
-
id: ++cache.messageIdCounter, role: 'system',
|
|
238
|
-
content: msg.content, isCommandOutput: true, timestamp: new Date(),
|
|
239
|
-
});
|
|
240
|
-
} else if (msg.type === 'ask_user_question') {
|
|
241
|
-
const msgs = cache.messages;
|
|
242
|
-
finalizeLastStreaming(msgs);
|
|
243
|
-
for (let i = msgs.length - 1; i >= 0; i--) {
|
|
244
|
-
const m = msgs[i];
|
|
245
|
-
if (m.role === 'tool' && m.toolName === 'AskUserQuestion') {
|
|
246
|
-
msgs.splice(i, 1);
|
|
247
|
-
break;
|
|
248
|
-
}
|
|
249
|
-
if (m.role === 'user') break;
|
|
250
|
-
}
|
|
251
|
-
const questions = msg.questions || [];
|
|
252
|
-
const selectedAnswers = {};
|
|
253
|
-
const customTexts = {};
|
|
254
|
-
for (let i = 0; i < questions.length; i++) {
|
|
255
|
-
selectedAnswers[i] = questions[i].multiSelect ? [] : null;
|
|
256
|
-
customTexts[i] = '';
|
|
257
|
-
}
|
|
258
|
-
msgs.push({
|
|
259
|
-
id: ++cache.messageIdCounter,
|
|
260
|
-
role: 'ask-question',
|
|
261
|
-
requestId: msg.requestId,
|
|
262
|
-
questions,
|
|
263
|
-
answered: false,
|
|
264
|
-
selectedAnswers,
|
|
265
|
-
customTexts,
|
|
266
|
-
timestamp: new Date(),
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
}
|