linkshell-cli 0.2.121 → 0.2.123
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/cli/src/runtime/acp/agent-workspace.js +64 -10
- package/dist/cli/src/runtime/acp/agent-workspace.js.map +1 -1
- package/dist/cli/src/runtime/acp/claude-sdk-client.js +19 -0
- package/dist/cli/src/runtime/acp/claude-sdk-client.js.map +1 -1
- package/dist/cli/src/runtime/acp/claude-stream-json-client.js +38 -1
- package/dist/cli/src/runtime/acp/claude-stream-json-client.js.map +1 -1
- package/dist/cli/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/runtime/acp/agent-workspace.ts +64 -10
- package/src/runtime/acp/claude-sdk-client.ts +19 -0
- package/src/runtime/acp/claude-stream-json-client.ts +39 -1
|
@@ -330,6 +330,50 @@ function textFromBlocks(blocks) {
|
|
|
330
330
|
.filter(Boolean)
|
|
331
331
|
.join("\n");
|
|
332
332
|
}
|
|
333
|
+
function contentBlocksFromValue(value) {
|
|
334
|
+
if (typeof value === "string") {
|
|
335
|
+
return value.trim() ? [{ type: "text", text: value }] : [];
|
|
336
|
+
}
|
|
337
|
+
if (Array.isArray(value)) {
|
|
338
|
+
return value.flatMap((entry) => contentBlocksFromValue(entry));
|
|
339
|
+
}
|
|
340
|
+
const raw = asRecord(value);
|
|
341
|
+
if (!raw)
|
|
342
|
+
return [];
|
|
343
|
+
const rawType = firstString(raw, ["type", "kind"]);
|
|
344
|
+
const normalizedType = normalizedIdentifier(rawType);
|
|
345
|
+
if (normalizedType === "image" || normalizedType === "inputimage" || normalizedType === "outputimage") {
|
|
346
|
+
const data = firstString(raw, [
|
|
347
|
+
"data",
|
|
348
|
+
"url",
|
|
349
|
+
"uri",
|
|
350
|
+
"imageUrl",
|
|
351
|
+
"image_url",
|
|
352
|
+
"base64",
|
|
353
|
+
]);
|
|
354
|
+
const mimeType = firstString(raw, ["mimeType", "mime_type", "mediaType", "media_type"]);
|
|
355
|
+
const text = firstString(raw, ["text", "alt", "caption", "name"]);
|
|
356
|
+
return [{ type: "image", data, mimeType, text }];
|
|
357
|
+
}
|
|
358
|
+
if (normalizedType === "text" || normalizedType === "outputtext" || normalizedType === "inputtext") {
|
|
359
|
+
const text = firstString(raw, ["text", "content", "message"]);
|
|
360
|
+
return text ? [{ type: "text", text }] : [];
|
|
361
|
+
}
|
|
362
|
+
const nested = raw.content ?? raw.contentItems ?? raw.parts;
|
|
363
|
+
if (Array.isArray(nested))
|
|
364
|
+
return contentBlocksFromValue(nested);
|
|
365
|
+
const text = firstString(raw, ["text", "message", "content"]);
|
|
366
|
+
return text ? [{ type: "text", text }] : [];
|
|
367
|
+
}
|
|
368
|
+
function contentBlocksFromItem(item) {
|
|
369
|
+
for (const key of ["content", "contentItems", "parts", "message"]) {
|
|
370
|
+
const blocks = contentBlocksFromValue(item[key]);
|
|
371
|
+
if (blocks.length > 0)
|
|
372
|
+
return blocks;
|
|
373
|
+
}
|
|
374
|
+
const text = firstString(item, ["text", "message"]);
|
|
375
|
+
return text ? [{ type: "text", text }] : [];
|
|
376
|
+
}
|
|
333
377
|
function protocolSupportsImages(protocol) {
|
|
334
378
|
return protocol === "codex-app-server" ||
|
|
335
379
|
protocol === "claude-agent-sdk" ||
|
|
@@ -1713,8 +1757,11 @@ export class AgentWorkspaceProxy {
|
|
|
1713
1757
|
if (agentSessionId && conversationId) {
|
|
1714
1758
|
this.conversationByAgentSessionId.set(agentSessionId, conversationId);
|
|
1715
1759
|
const conversation = this.conversations.get(conversationId);
|
|
1716
|
-
if (conversation)
|
|
1760
|
+
if (conversation) {
|
|
1717
1761
|
conversation.agentSessionId = agentSessionId;
|
|
1762
|
+
conversation.lastActivityAt = Date.now();
|
|
1763
|
+
this.emitConversation(conversation);
|
|
1764
|
+
}
|
|
1718
1765
|
}
|
|
1719
1766
|
return;
|
|
1720
1767
|
}
|
|
@@ -2058,28 +2105,33 @@ export class AgentWorkspaceProxy {
|
|
|
2058
2105
|
return;
|
|
2059
2106
|
const itemId = firstString(item, ["id"]) ?? id("msg");
|
|
2060
2107
|
const existing = this.findItem(conversationId, itemId);
|
|
2061
|
-
const content =
|
|
2062
|
-
|
|
2108
|
+
const content = contentBlocksFromItem(item);
|
|
2109
|
+
const nextContent = content.length > 0
|
|
2110
|
+
? content
|
|
2111
|
+
: existing?.content ?? (existing?.text ? [{ type: "text", text: existing.text }] : []);
|
|
2112
|
+
const text = textFromBlocks(nextContent);
|
|
2113
|
+
if (!nextContent.length && !text)
|
|
2063
2114
|
return;
|
|
2064
2115
|
this.upsertItem(conversationId, {
|
|
2065
2116
|
id: itemId,
|
|
2066
2117
|
conversationId,
|
|
2067
2118
|
type: "message",
|
|
2068
2119
|
role: "assistant",
|
|
2069
|
-
content:
|
|
2070
|
-
text
|
|
2120
|
+
content: nextContent,
|
|
2121
|
+
text,
|
|
2071
2122
|
createdAt: existing?.createdAt ?? Date.now(),
|
|
2072
2123
|
updatedAt: Date.now(),
|
|
2073
2124
|
isStreaming: streaming,
|
|
2074
2125
|
});
|
|
2075
|
-
this.updateConversationPreview(conversationId,
|
|
2126
|
+
this.updateConversationPreview(conversationId, text || "图片附件", streaming ? "running" : "idle");
|
|
2076
2127
|
}
|
|
2077
2128
|
handleSessionUpdate(params) {
|
|
2078
2129
|
const raw = asRecord(params) ?? {};
|
|
2079
2130
|
const nested = asRecord(raw.params) ?? {};
|
|
2080
2131
|
const text = firstString(raw, ["delta", "text", "content", "message"]) ??
|
|
2081
2132
|
firstString(nested, ["delta", "text", "content", "message"]);
|
|
2082
|
-
|
|
2133
|
+
const content = contentBlocksFromItem(raw);
|
|
2134
|
+
if (!text && content.length === 0)
|
|
2083
2135
|
return;
|
|
2084
2136
|
const conversationId = this.conversationIdFromParams(raw) ?? this.fallbackConversationId();
|
|
2085
2137
|
if (!conversationId)
|
|
@@ -2098,18 +2150,20 @@ export class AgentWorkspaceProxy {
|
|
|
2098
2150
|
return;
|
|
2099
2151
|
}
|
|
2100
2152
|
const role = raw.role === "user" || raw.role === "system" ? raw.role : "assistant";
|
|
2153
|
+
const blocks = content.length > 0 ? content : [{ type: "text", text }];
|
|
2154
|
+
const preview = textFromBlocks(blocks);
|
|
2101
2155
|
this.upsertItem(conversationId, {
|
|
2102
2156
|
id: firstString(raw, ["messageId", "id"]) ?? id("msg"),
|
|
2103
2157
|
conversationId,
|
|
2104
2158
|
type: "message",
|
|
2105
2159
|
role,
|
|
2106
|
-
content:
|
|
2107
|
-
text,
|
|
2160
|
+
content: blocks,
|
|
2161
|
+
text: preview,
|
|
2108
2162
|
createdAt: Date.now(),
|
|
2109
2163
|
updatedAt: Date.now(),
|
|
2110
2164
|
isStreaming: raw.done === false || raw.isStreaming === true,
|
|
2111
2165
|
});
|
|
2112
|
-
this.updateConversationPreview(conversationId,
|
|
2166
|
+
this.updateConversationPreview(conversationId, preview || "图片附件", raw.done === true ? "idle" : "running");
|
|
2113
2167
|
}
|
|
2114
2168
|
handleSemanticSystemItem(item, status, streaming) {
|
|
2115
2169
|
const itemType = firstString(item, ["type"]);
|