linkshell-cli 0.2.114 → 0.2.115
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.d.ts +6 -0
- package/dist/cli/src/runtime/acp/agent-workspace.js +141 -39
- package/dist/cli/src/runtime/acp/agent-workspace.js.map +1 -1
- package/dist/cli/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/runtime/acp/agent-workspace.ts +139 -37
|
@@ -1207,6 +1207,7 @@ export class AgentWorkspaceProxy {
|
|
|
1207
1207
|
private error: string | undefined;
|
|
1208
1208
|
private activeConversationId: string | undefined;
|
|
1209
1209
|
private currentTurnIds = new Map<string, string>();
|
|
1210
|
+
private turnConversationIds = new Map<string, string>();
|
|
1210
1211
|
private conversations = new Map<string, AgentConversation>();
|
|
1211
1212
|
private conversationByAgentSessionId = new Map<string, string>();
|
|
1212
1213
|
private timelines = new Map<string, AgentTimelineItem[]>();
|
|
@@ -1216,6 +1217,7 @@ export class AgentWorkspaceProxy {
|
|
|
1216
1217
|
private permissionSources = new Map<string, string>();
|
|
1217
1218
|
private pendingStructuredInputs = new Map<string, { conversationId: string; input: AgentStructuredInput }>();
|
|
1218
1219
|
private structuredInputWaiters = new Map<string, PendingStructuredInputWaiter>();
|
|
1220
|
+
private itemConversationIds = new Map<string, string>();
|
|
1219
1221
|
private toolConversationIds = new Map<string, string>();
|
|
1220
1222
|
|
|
1221
1223
|
constructor(
|
|
@@ -1277,7 +1279,7 @@ export class AgentWorkspaceProxy {
|
|
|
1277
1279
|
sessionId: conversation?.agentSessionId,
|
|
1278
1280
|
turnId: this.currentTurnIds.get(payload.conversationId),
|
|
1279
1281
|
});
|
|
1280
|
-
this.
|
|
1282
|
+
this.forgetCurrentTurn(payload.conversationId);
|
|
1281
1283
|
this.updateConversationStatus(payload.conversationId, "idle");
|
|
1282
1284
|
this.emitStatus(payload.conversationId, "idle", "已停止");
|
|
1283
1285
|
break;
|
|
@@ -1769,7 +1771,7 @@ export class AgentWorkspaceProxy {
|
|
|
1769
1771
|
this.conversationByAgentSessionId.set(nextAgentSessionId, conversation.id);
|
|
1770
1772
|
}
|
|
1771
1773
|
const turnId = this.extractTurnId(result);
|
|
1772
|
-
if (turnId) this.
|
|
1774
|
+
if (turnId) this.rememberTurnConversationId(conversation.id, turnId);
|
|
1773
1775
|
if (conversation.status === "running" && protocol !== "codex-app-server") {
|
|
1774
1776
|
this.updateConversationStatus(conversation.id, "idle");
|
|
1775
1777
|
}
|
|
@@ -2007,7 +2009,7 @@ export class AgentWorkspaceProxy {
|
|
|
2007
2009
|
process.stderr.write(`[agent:v2] ${method} ${stringify(params).slice(0, 500)}\n`);
|
|
2008
2010
|
}
|
|
2009
2011
|
if (method === "initialized") {
|
|
2010
|
-
const conversationId = this.conversationIdFromParams(params) ?? this.
|
|
2012
|
+
const conversationId = this.conversationIdFromParams(params) ?? this.fallbackConversationId();
|
|
2011
2013
|
const provider = conversationId ? this.conversations.get(conversationId)?.provider : this.input.availableProviders[0];
|
|
2012
2014
|
if (provider) {
|
|
2013
2015
|
const commands = runtimeCommands(provider, params);
|
|
@@ -2033,7 +2035,7 @@ export class AgentWorkspaceProxy {
|
|
|
2033
2035
|
return;
|
|
2034
2036
|
}
|
|
2035
2037
|
|
|
2036
|
-
const conversationId = this.conversationIdFromParams(params) ?? this.
|
|
2038
|
+
const conversationId = this.conversationIdFromParams(params) ?? this.fallbackConversationId();
|
|
2037
2039
|
if (method === "item/tool/requestUserInput" || method === "tool/requestUserInput") {
|
|
2038
2040
|
this.handleStructuredInput(params);
|
|
2039
2041
|
return;
|
|
@@ -2058,14 +2060,14 @@ export class AgentWorkspaceProxy {
|
|
|
2058
2060
|
if (method === "turn/started") {
|
|
2059
2061
|
if (conversationId) {
|
|
2060
2062
|
const turnId = this.extractTurnId(params);
|
|
2061
|
-
if (turnId) this.
|
|
2063
|
+
if (turnId) this.rememberTurnConversationId(conversationId, turnId);
|
|
2062
2064
|
this.updateConversationStatus(conversationId, "running");
|
|
2063
2065
|
}
|
|
2064
2066
|
return;
|
|
2065
2067
|
}
|
|
2066
2068
|
if (method === "turn/completed") {
|
|
2067
2069
|
if (conversationId) {
|
|
2068
|
-
this.
|
|
2070
|
+
this.forgetCurrentTurn(conversationId, this.extractTurnId(params));
|
|
2069
2071
|
this.updateConversationStatus(conversationId, "idle");
|
|
2070
2072
|
}
|
|
2071
2073
|
return;
|
|
@@ -2124,7 +2126,7 @@ export class AgentWorkspaceProxy {
|
|
|
2124
2126
|
private handleAgentMessageDelta(params: unknown): void {
|
|
2125
2127
|
const raw = asRecord(params);
|
|
2126
2128
|
if (!raw) return;
|
|
2127
|
-
const conversationId = this.conversationIdFromParams(raw) ?? this.
|
|
2129
|
+
const conversationId = this.conversationIdFromParams(raw) ?? this.fallbackConversationId();
|
|
2128
2130
|
if (!conversationId) return;
|
|
2129
2131
|
const itemId = firstString(raw, ["itemId", "id", "messageId"]) ?? id("msg");
|
|
2130
2132
|
const delta = firstString(raw, ["delta", "text", "content"]);
|
|
@@ -2148,7 +2150,7 @@ export class AgentWorkspaceProxy {
|
|
|
2148
2150
|
|
|
2149
2151
|
private handlePlanUpdated(params: unknown): void {
|
|
2150
2152
|
const raw = asRecord(params);
|
|
2151
|
-
const conversationId = this.conversationIdFromParams(raw) ?? this.
|
|
2153
|
+
const conversationId = this.conversationIdFromParams(raw) ?? this.fallbackConversationId();
|
|
2152
2154
|
if (!conversationId) return;
|
|
2153
2155
|
const plan = Array.isArray(raw?.plan) ? raw.plan : [];
|
|
2154
2156
|
const steps = plan
|
|
@@ -2177,7 +2179,7 @@ export class AgentWorkspaceProxy {
|
|
|
2177
2179
|
private handlePlanDelta(params: unknown): void {
|
|
2178
2180
|
const raw = asRecord(params);
|
|
2179
2181
|
if (!raw) return;
|
|
2180
|
-
const conversationId = this.conversationIdFromParams(raw) ?? this.
|
|
2182
|
+
const conversationId = this.conversationIdFromParams(raw) ?? this.fallbackConversationId();
|
|
2181
2183
|
if (!conversationId) return;
|
|
2182
2184
|
const itemId = firstString(raw, ["itemId", "id"]) ?? "plan";
|
|
2183
2185
|
const delta = firstString(raw, ["delta", "text"]);
|
|
@@ -2199,23 +2201,25 @@ export class AgentWorkspaceProxy {
|
|
|
2199
2201
|
private handleItemStarted(params: unknown): void {
|
|
2200
2202
|
const item = extractItem(params);
|
|
2201
2203
|
if (!item) return;
|
|
2202
|
-
const
|
|
2204
|
+
const sourceConversationId = this.conversationIdFromParams(params);
|
|
2205
|
+
const routedItem = sourceConversationId ? { ...item, conversationId: sourceConversationId } : item;
|
|
2206
|
+
const itemType = firstString(routedItem, ["type"]);
|
|
2203
2207
|
const normalizedItemType = normalizedIdentifier(itemType);
|
|
2204
2208
|
if (normalizedItemType === "agentmessage" || normalizedItemType === "assistantmessage") {
|
|
2205
|
-
this.handleCompletedMessageItem(
|
|
2209
|
+
this.handleCompletedMessageItem(routedItem, true);
|
|
2206
2210
|
return;
|
|
2207
2211
|
}
|
|
2208
2212
|
if (normalizedItemType === "plan") {
|
|
2209
|
-
this.handlePlanUpdated({ plan: [
|
|
2213
|
+
this.handlePlanUpdated({ plan: [routedItem], conversationId: sourceConversationId });
|
|
2210
2214
|
return;
|
|
2211
2215
|
}
|
|
2212
2216
|
if (isSubagentItemType(itemType)) {
|
|
2213
|
-
this.handleSubagentItem(
|
|
2217
|
+
this.handleSubagentItem(routedItem, "running", true);
|
|
2214
2218
|
return;
|
|
2215
2219
|
}
|
|
2216
|
-
if (this.handleSemanticSystemItem(
|
|
2217
|
-
const conversationId = this.conversationIdFromParams(
|
|
2218
|
-
const toolCall = this.toolCallFromItem(
|
|
2220
|
+
if (this.handleSemanticSystemItem(routedItem, "running", true)) return;
|
|
2221
|
+
const conversationId = this.conversationIdFromParams(routedItem) ?? this.fallbackConversationId();
|
|
2222
|
+
const toolCall = this.toolCallFromItem(routedItem, "running");
|
|
2219
2223
|
if (!conversationId || !toolCall) return;
|
|
2220
2224
|
this.toolConversationIds.set(toolCall.id, conversationId);
|
|
2221
2225
|
this.upsertTool(conversationId, toolCall);
|
|
@@ -2224,23 +2228,25 @@ export class AgentWorkspaceProxy {
|
|
|
2224
2228
|
private handleItemCompleted(params: unknown): void {
|
|
2225
2229
|
const item = extractItem(params);
|
|
2226
2230
|
if (!item) return;
|
|
2227
|
-
const
|
|
2231
|
+
const sourceConversationId = this.conversationIdFromParams(params);
|
|
2232
|
+
const routedItem = sourceConversationId ? { ...item, conversationId: sourceConversationId } : item;
|
|
2233
|
+
const itemType = firstString(routedItem, ["type"]);
|
|
2228
2234
|
const normalizedItemType = normalizedIdentifier(itemType);
|
|
2229
2235
|
if (normalizedItemType === "agentmessage" || normalizedItemType === "assistantmessage") {
|
|
2230
|
-
this.handleCompletedMessageItem(
|
|
2236
|
+
this.handleCompletedMessageItem(routedItem, false);
|
|
2231
2237
|
return;
|
|
2232
2238
|
}
|
|
2233
2239
|
if (normalizedItemType === "plan") {
|
|
2234
|
-
this.handlePlanDelta({ ...
|
|
2240
|
+
this.handlePlanDelta({ ...routedItem, delta: firstString(routedItem, ["text", "content", "message"]) });
|
|
2235
2241
|
return;
|
|
2236
2242
|
}
|
|
2237
2243
|
if (isSubagentItemType(itemType)) {
|
|
2238
|
-
this.handleSubagentItem(
|
|
2244
|
+
this.handleSubagentItem(routedItem, normalizeToolStatus(routedItem.status, true), false);
|
|
2239
2245
|
return;
|
|
2240
2246
|
}
|
|
2241
|
-
if (this.handleSemanticSystemItem(
|
|
2242
|
-
const conversationId = this.conversationIdFromParams(
|
|
2243
|
-
const toolCall = this.toolCallFromItem(
|
|
2247
|
+
if (this.handleSemanticSystemItem(routedItem, normalizeToolStatus(routedItem.status, true), false)) return;
|
|
2248
|
+
const conversationId = this.conversationIdFromParams(routedItem) ?? this.fallbackConversationId();
|
|
2249
|
+
const toolCall = this.toolCallFromItem(routedItem, normalizeToolStatus(routedItem.status, true));
|
|
2244
2250
|
if (!conversationId || !toolCall) return;
|
|
2245
2251
|
const bufferedOutput = this.toolOutputBuffers.get(toolCall.id);
|
|
2246
2252
|
if (bufferedOutput && !toolCall.output) toolCall.output = bufferedOutput;
|
|
@@ -2256,7 +2262,8 @@ export class AgentWorkspaceProxy {
|
|
|
2256
2262
|
const conversationId =
|
|
2257
2263
|
this.conversationIdFromParams(raw) ??
|
|
2258
2264
|
this.toolConversationIds.get(itemId) ??
|
|
2259
|
-
this.
|
|
2265
|
+
this.itemConversationIds.get(itemId) ??
|
|
2266
|
+
this.fallbackConversationId();
|
|
2260
2267
|
if (!conversationId) return;
|
|
2261
2268
|
const output = appendCapped(this.toolOutputBuffers.get(itemId), delta, 6000);
|
|
2262
2269
|
this.toolOutputBuffers.set(itemId, output);
|
|
@@ -2278,7 +2285,8 @@ export class AgentWorkspaceProxy {
|
|
|
2278
2285
|
const conversationId =
|
|
2279
2286
|
this.conversationIdFromParams(raw) ??
|
|
2280
2287
|
this.toolConversationIds.get(itemId) ??
|
|
2281
|
-
this.
|
|
2288
|
+
this.itemConversationIds.get(itemId) ??
|
|
2289
|
+
this.fallbackConversationId();
|
|
2282
2290
|
if (!conversationId) return;
|
|
2283
2291
|
const output =
|
|
2284
2292
|
extractDiffText(raw) ??
|
|
@@ -2297,7 +2305,7 @@ export class AgentWorkspaceProxy {
|
|
|
2297
2305
|
private handleTurnDiffUpdated(params: unknown): void {
|
|
2298
2306
|
const raw = asRecord(params);
|
|
2299
2307
|
if (!raw) return;
|
|
2300
|
-
const conversationId = this.conversationIdFromParams(raw) ?? this.
|
|
2308
|
+
const conversationId = this.conversationIdFromParams(raw) ?? this.fallbackConversationId();
|
|
2301
2309
|
if (!conversationId) return;
|
|
2302
2310
|
const diff = extractDiffText(raw);
|
|
2303
2311
|
if (!diff) return;
|
|
@@ -2327,7 +2335,8 @@ export class AgentWorkspaceProxy {
|
|
|
2327
2335
|
const conversationId =
|
|
2328
2336
|
this.conversationIdFromParams(raw) ??
|
|
2329
2337
|
this.toolConversationIds.get(processId) ??
|
|
2330
|
-
this.
|
|
2338
|
+
this.itemConversationIds.get(processId) ??
|
|
2339
|
+
this.fallbackConversationId();
|
|
2331
2340
|
if (!conversationId) return;
|
|
2332
2341
|
const output = appendCapped(this.toolOutputBuffers.get(processId), delta, 6000);
|
|
2333
2342
|
this.toolOutputBuffers.set(processId, output);
|
|
@@ -2344,7 +2353,7 @@ export class AgentWorkspaceProxy {
|
|
|
2344
2353
|
|
|
2345
2354
|
private handleAutoApprovalReview(params: unknown, streaming: boolean): void {
|
|
2346
2355
|
const raw = asRecord(params) ?? {};
|
|
2347
|
-
const conversationId = this.conversationIdFromParams(raw) ?? this.
|
|
2356
|
+
const conversationId = this.conversationIdFromParams(raw) ?? this.fallbackConversationId();
|
|
2348
2357
|
if (!conversationId) return;
|
|
2349
2358
|
const itemId = firstString(raw, ["itemId", "id", "reviewId"]) ?? "auto-approval-review";
|
|
2350
2359
|
const existing = this.findItem(conversationId, itemId);
|
|
@@ -2374,7 +2383,7 @@ export class AgentWorkspaceProxy {
|
|
|
2374
2383
|
}
|
|
2375
2384
|
|
|
2376
2385
|
private handleCompletedMessageItem(item: Record<string, unknown>, streaming: boolean): void {
|
|
2377
|
-
const conversationId = this.conversationIdFromParams(item) ?? this.
|
|
2386
|
+
const conversationId = this.conversationIdFromParams(item) ?? this.fallbackConversationId();
|
|
2378
2387
|
if (!conversationId) return;
|
|
2379
2388
|
const itemId = firstString(item, ["id"]) ?? id("msg");
|
|
2380
2389
|
const existing = this.findItem(conversationId, itemId);
|
|
@@ -2401,7 +2410,7 @@ export class AgentWorkspaceProxy {
|
|
|
2401
2410
|
firstString(raw, ["delta", "text", "content", "message"]) ??
|
|
2402
2411
|
firstString(nested, ["delta", "text", "content", "message"]);
|
|
2403
2412
|
if (!text) return;
|
|
2404
|
-
const conversationId = this.conversationIdFromParams(raw) ?? this.
|
|
2413
|
+
const conversationId = this.conversationIdFromParams(raw) ?? this.fallbackConversationId();
|
|
2405
2414
|
if (!conversationId) return;
|
|
2406
2415
|
if (firstString(raw, ["toolName", "tool", "name"])) {
|
|
2407
2416
|
this.upsertTool(conversationId, {
|
|
@@ -2438,7 +2447,7 @@ export class AgentWorkspaceProxy {
|
|
|
2438
2447
|
): boolean {
|
|
2439
2448
|
const itemType = firstString(item, ["type"]);
|
|
2440
2449
|
const normalized = normalizedIdentifier(itemType);
|
|
2441
|
-
const conversationId = this.conversationIdFromParams(item) ?? this.
|
|
2450
|
+
const conversationId = this.conversationIdFromParams(item) ?? this.fallbackConversationId();
|
|
2442
2451
|
if (!conversationId) return false;
|
|
2443
2452
|
const itemId = firstString(item, ["id", "itemId"]) ?? id("item");
|
|
2444
2453
|
const existing = this.findItem(conversationId, itemId);
|
|
@@ -2493,7 +2502,7 @@ export class AgentWorkspaceProxy {
|
|
|
2493
2502
|
status: AgentToolCall["status"],
|
|
2494
2503
|
streaming: boolean,
|
|
2495
2504
|
): void {
|
|
2496
|
-
const conversationId = this.conversationIdFromParams(item) ?? this.
|
|
2505
|
+
const conversationId = this.conversationIdFromParams(item) ?? this.fallbackConversationId();
|
|
2497
2506
|
if (!conversationId) return;
|
|
2498
2507
|
const subagent = decodeSubagentAction(item, status);
|
|
2499
2508
|
if (!subagent) return;
|
|
@@ -2519,7 +2528,7 @@ export class AgentWorkspaceProxy {
|
|
|
2519
2528
|
|
|
2520
2529
|
private handleStructuredInput(params: unknown, waitForResponse = false): Promise<unknown> | void {
|
|
2521
2530
|
const raw = asRecord(params) ?? {};
|
|
2522
|
-
const conversationId = this.conversationIdFromParams(raw) ?? this.
|
|
2531
|
+
const conversationId = this.conversationIdFromParams(raw) ?? this.fallbackConversationId();
|
|
2523
2532
|
const source = firstString(raw, ["method", "source", "requestMethod"]);
|
|
2524
2533
|
const formatResponse = source === "mcpServer/elicitation/request"
|
|
2525
2534
|
? formatMcpElicitationResponse
|
|
@@ -2590,7 +2599,7 @@ export class AgentWorkspaceProxy {
|
|
|
2590
2599
|
source?: string,
|
|
2591
2600
|
): Promise<unknown> | void {
|
|
2592
2601
|
const raw = asRecord(params) ?? {};
|
|
2593
|
-
const conversationId = this.conversationIdFromParams(raw) ?? this.
|
|
2602
|
+
const conversationId = this.conversationIdFromParams(raw) ?? this.fallbackConversationId();
|
|
2594
2603
|
if (!conversationId) return waitForResponse ? Promise.resolve({ outcome: { outcome: "cancelled" } }) : undefined;
|
|
2595
2604
|
const requestId = firstString(raw, ["requestId", "id", "permissionId"]) ?? id("perm");
|
|
2596
2605
|
const rawToolCall = asRecord(raw.toolCall) ?? raw;
|
|
@@ -2726,6 +2735,7 @@ export class AgentWorkspaceProxy {
|
|
|
2726
2735
|
}
|
|
2727
2736
|
|
|
2728
2737
|
private addItem(conversationId: string, item: AgentTimelineItem): void {
|
|
2738
|
+
this.rememberItemConversationId(conversationId, item);
|
|
2729
2739
|
const timeline = this.timelines.get(conversationId) ?? [];
|
|
2730
2740
|
timeline.push(item);
|
|
2731
2741
|
timeline.sort((a, b) => a.createdAt - b.createdAt);
|
|
@@ -2737,6 +2747,7 @@ export class AgentWorkspaceProxy {
|
|
|
2737
2747
|
}
|
|
2738
2748
|
|
|
2739
2749
|
private upsertItem(conversationId: string, item: AgentTimelineItem): void {
|
|
2750
|
+
this.rememberItemConversationId(conversationId, item);
|
|
2740
2751
|
const timeline = this.timelines.get(conversationId) ?? [];
|
|
2741
2752
|
const index = timeline.findIndex((entry) => entry.id === item.id);
|
|
2742
2753
|
if (index >= 0) timeline[index] = item;
|
|
@@ -2764,6 +2775,8 @@ export class AgentWorkspaceProxy {
|
|
|
2764
2775
|
};
|
|
2765
2776
|
this.toolConversationIds.set(toolCall.id, conversationId);
|
|
2766
2777
|
this.toolConversationIds.set(nextToolCall.id, conversationId);
|
|
2778
|
+
this.itemConversationIds.set(toolCall.id, conversationId);
|
|
2779
|
+
this.itemConversationIds.set(nextToolCall.id, conversationId);
|
|
2767
2780
|
const kind: AgentTimelineKind = nextToolCall.name.includes("文件")
|
|
2768
2781
|
? "file_change"
|
|
2769
2782
|
: nextToolCall.name.includes("命令")
|
|
@@ -2863,6 +2876,22 @@ export class AgentWorkspaceProxy {
|
|
|
2863
2876
|
this.toolConversationIds.set(toolId, newId);
|
|
2864
2877
|
}
|
|
2865
2878
|
}
|
|
2879
|
+
for (const [turnId, conversationId] of this.turnConversationIds) {
|
|
2880
|
+
if (conversationId === oldId) {
|
|
2881
|
+
this.turnConversationIds.set(turnId, newId);
|
|
2882
|
+
}
|
|
2883
|
+
}
|
|
2884
|
+
const currentTurnId = this.currentTurnIds.get(oldId);
|
|
2885
|
+
if (currentTurnId) {
|
|
2886
|
+
this.currentTurnIds.delete(oldId);
|
|
2887
|
+
this.currentTurnIds.set(newId, currentTurnId);
|
|
2888
|
+
this.turnConversationIds.set(currentTurnId, newId);
|
|
2889
|
+
}
|
|
2890
|
+
for (const [itemId, conversationId] of this.itemConversationIds) {
|
|
2891
|
+
if (conversationId === oldId) {
|
|
2892
|
+
this.itemConversationIds.set(itemId, newId);
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2866
2895
|
if (this.activeConversationId === oldId) {
|
|
2867
2896
|
this.activeConversationId = newId;
|
|
2868
2897
|
}
|
|
@@ -2941,13 +2970,86 @@ export class AgentWorkspaceProxy {
|
|
|
2941
2970
|
|
|
2942
2971
|
private conversationIdFromParams(params: unknown): string | undefined {
|
|
2943
2972
|
const raw = asRecord(params);
|
|
2944
|
-
|
|
2945
|
-
|
|
2973
|
+
if (!raw) return undefined;
|
|
2974
|
+
const directConversationId = firstString(raw, ["conversationId"]);
|
|
2975
|
+
if (directConversationId && this.conversations.has(directConversationId)) {
|
|
2976
|
+
return directConversationId;
|
|
2977
|
+
}
|
|
2946
2978
|
const threadId = firstString(raw, ["threadId", "sessionId", "agentSessionId"]);
|
|
2947
|
-
if (threadId)
|
|
2979
|
+
if (threadId) {
|
|
2980
|
+
const conversationId = this.conversationByAgentSessionId.get(threadId);
|
|
2981
|
+
if (conversationId) return conversationId;
|
|
2982
|
+
}
|
|
2983
|
+
const agentSessionId = this.extractSessionId(raw);
|
|
2984
|
+
if (agentSessionId) {
|
|
2985
|
+
const conversationId = this.conversationByAgentSessionId.get(agentSessionId);
|
|
2986
|
+
if (conversationId) return conversationId;
|
|
2987
|
+
}
|
|
2988
|
+
const turnId = this.extractTurnId(raw) ?? firstString(raw, ["turnId"]);
|
|
2989
|
+
if (turnId) {
|
|
2990
|
+
const conversationId = this.turnConversationIds.get(turnId);
|
|
2991
|
+
if (conversationId) return conversationId;
|
|
2992
|
+
}
|
|
2993
|
+
const itemId = firstString(raw, [
|
|
2994
|
+
"itemId",
|
|
2995
|
+
"messageId",
|
|
2996
|
+
"toolCallId",
|
|
2997
|
+
"processId",
|
|
2998
|
+
"callId",
|
|
2999
|
+
"requestId",
|
|
3000
|
+
"permissionId",
|
|
3001
|
+
"id",
|
|
3002
|
+
]);
|
|
3003
|
+
if (itemId) {
|
|
3004
|
+
const conversationId =
|
|
3005
|
+
this.itemConversationIds.get(itemId) ??
|
|
3006
|
+
this.toolConversationIds.get(itemId);
|
|
3007
|
+
if (conversationId) return conversationId;
|
|
3008
|
+
}
|
|
3009
|
+
for (const nested of [raw.params, raw.item, raw.message, raw.toolCall, raw.command, raw.event]) {
|
|
3010
|
+
const nestedRecord = asRecord(nested);
|
|
3011
|
+
if (!nestedRecord || nestedRecord === raw) continue;
|
|
3012
|
+
const conversationId = this.conversationIdFromParams(nestedRecord);
|
|
3013
|
+
if (conversationId) return conversationId;
|
|
3014
|
+
}
|
|
2948
3015
|
return undefined;
|
|
2949
3016
|
}
|
|
2950
3017
|
|
|
3018
|
+
private fallbackConversationId(): string | undefined {
|
|
3019
|
+
const liveConversations = [...this.conversations.values()].filter((conversation) =>
|
|
3020
|
+
conversation.status === "running" || conversation.status === "waiting_permission",
|
|
3021
|
+
);
|
|
3022
|
+
return liveConversations.length === 1 ? liveConversations[0]?.id : undefined;
|
|
3023
|
+
}
|
|
3024
|
+
|
|
3025
|
+
private rememberTurnConversationId(conversationId: string, turnId: string): void {
|
|
3026
|
+
this.currentTurnIds.set(conversationId, turnId);
|
|
3027
|
+
this.turnConversationIds.set(turnId, conversationId);
|
|
3028
|
+
}
|
|
3029
|
+
|
|
3030
|
+
private forgetCurrentTurn(conversationId: string, turnId?: string): void {
|
|
3031
|
+
const currentTurnId = this.currentTurnIds.get(conversationId);
|
|
3032
|
+
this.currentTurnIds.delete(conversationId);
|
|
3033
|
+
if (turnId) this.turnConversationIds.delete(turnId);
|
|
3034
|
+
if (currentTurnId && currentTurnId !== turnId) this.turnConversationIds.delete(currentTurnId);
|
|
3035
|
+
}
|
|
3036
|
+
|
|
3037
|
+
private rememberItemConversationId(conversationId: string, item: AgentTimelineItem): void {
|
|
3038
|
+
const keys = [
|
|
3039
|
+
item.id,
|
|
3040
|
+
item.itemId,
|
|
3041
|
+
item.toolCall?.id,
|
|
3042
|
+
item.permission?.requestId,
|
|
3043
|
+
item.structuredInput?.requestId,
|
|
3044
|
+
].filter((key): key is string => Boolean(key));
|
|
3045
|
+
for (const key of keys) {
|
|
3046
|
+
this.itemConversationIds.set(key, conversationId);
|
|
3047
|
+
}
|
|
3048
|
+
if (item.turnId) {
|
|
3049
|
+
this.turnConversationIds.set(item.turnId, conversationId);
|
|
3050
|
+
}
|
|
3051
|
+
}
|
|
3052
|
+
|
|
2951
3053
|
private handleProviderExit(provider: AgentProvider, message: string): void {
|
|
2952
3054
|
this.clients.delete(provider);
|
|
2953
3055
|
this.agentProtocols.delete(provider);
|