1292
*/
1293
private _resolveSideChatOrigin(session: URI, sideChat: IAgentCreateChatSideChatSource): { origin: ChatOrigin; sourceChat: string; selection?: IAgentCreateChatSideChatSelection; providerAnchorTurnId?: string; sourceContext?: string; partialResponse?: string } {
1295
>
const sourceKey = sideChat.source.toString();
1296
>
const { sourceChatKey, sourceSessionKey, sourceState } = this._resolveSessionSourceChat(session, sideChat.source);
1297
>
// The source chat MUST belong to the target session. Older callers may
1298
>
// still address the main chat by session URI; synced AHP clients send the
1299
>
// actual default-chat URI.
1300
>
if (sourceSessionKey !== sessionKey) {
1301
throw new Error(`[AgentService] createChat: side chat source ${sourceKey} does not belong to session ${sessionKey}`);
1302
}
1303
// The bounded turn must be a real completed or currently-active turn.
1304
>
const activeTurn = sourceState?.activeTurn?.id === sideChat.turnId ? sourceState.activeTurn : undefined;
agentService.ts
1305
>
const hasCompletedTurn = sourceState?.turns.some(t => t.id === sideChat.turnId) ?? false;
1306
>
if (!hasCompletedTurn && !activeTurn) {
1307
throw new Error(`[AgentService] createChat: side chat source turn ${sideChat.turnId} not found in ${sourceKey}`);
1308
}
1309
const isLocalSourceTurn = !activeTurn && this._localTurns.isLocal(sourceChatKey, sideChat.turnId);
1310
>
const providerAnchorTurnId = isLocalSourceTurn ? this._localTurns.resolveConcreteTurnId(sourceChatKey, sideChat.turnId) : undefined;
agentService.ts
1311
>
const partialResponse = getSideChatPartialResponse(activeTurn);
1312
>
const sourceContext = (activeTurn || isLocalSourceTurn)
1313
? buildBoundedSideChatSourceContext(sourceState?.turns ?? [], sideChat.turnId, activeTurn)
1314
: undefined;
1316
? sideChat.selection
1317
: sideChat.selection
1318
? (() => { throw new Error('[AgentService] createChat: side chat selection text must be non-empty'); })()
1319
: undefined;
1321
>
origin: {
1322
>
kind: ChatOriginKind.SideChat,
1323
>
chat: sourceChatKey,
1324
>
turnId: sideChat.turnId,
1325
>
...(selection ? { selection } : {}),
1326
>
},
1327
>
sourceChat: sourceChatKey,
1328
>
...(selection ? { selection } : {}),
1329
>
...(providerAnchorTurnId ? { providerAnchorTurnId } : {}),
1330
>
...(sourceContext ? { sourceContext } : {}),
1331
>
...(partialResponse ? { partialResponse } : {}),
1332
>
};
1333
>
}
1334
1335
private _resolveSessionSourceChat(session: URI, source: URI): { sourceChatKey: string; sourceSessionKey: string; sourceState: ReturnType<AgentHostStateManager['getChatState']> | undefined } {
1337
>
const sourceKey = source.toString();
1338
>
const sourceSessionKey = isAhpChatChannel(sourceKey) ? parseRequiredSessionUriFromChatUri(sourceKey) : sourceKey;
1339
>
const defaultChatKey = this._stateManager.getSessionState(sessionKey)?.defaultChat ?? buildDefaultChatUri(sessionKey);
1340
>
const sourceChatKey = sourceKey === sessionKey
1341
? defaultChatKey
1342
: this._stateManager.getChatState(sourceKey)