fix(logs): scope graph preview lane requests
This commit is contained in:
parent
7c39fbd8e7
commit
0f9f79da66
5 changed files with 42 additions and 13 deletions
|
|
@ -26,10 +26,18 @@ function buildRequestKey(input: {
|
|||
textLimit: number;
|
||||
forceRefresh?: boolean;
|
||||
}): string {
|
||||
const laneEntries = Object.entries(input.laneIdsByMember)
|
||||
.map(([memberName, laneId]) => [normalizeMemberName(memberName), laneId.trim()] as const)
|
||||
.filter(([, laneId]) => laneId.length > 0)
|
||||
.sort((left, right) => left[0].localeCompare(right[0]));
|
||||
const laneEntriesByMember = new Map<string, string>();
|
||||
for (const [memberName, laneId] of Object.entries(input.laneIdsByMember)) {
|
||||
const normalizedMemberName = normalizeMemberName(memberName);
|
||||
const trimmedLaneId = laneId.trim();
|
||||
if (!normalizedMemberName || !trimmedLaneId || laneEntriesByMember.has(normalizedMemberName)) {
|
||||
continue;
|
||||
}
|
||||
laneEntriesByMember.set(normalizedMemberName, trimmedLaneId);
|
||||
}
|
||||
const laneEntries = Array.from(laneEntriesByMember.entries()).sort((left, right) =>
|
||||
left[0].localeCompare(right[0])
|
||||
);
|
||||
return JSON.stringify([
|
||||
input.teamName,
|
||||
input.memberNames.map(normalizeMemberName).sort((left, right) => left.localeCompare(right)),
|
||||
|
|
@ -84,6 +92,23 @@ function buildMemberCacheKey(input: {
|
|||
]);
|
||||
}
|
||||
|
||||
function buildLaneIdsForMembers(
|
||||
memberNames: readonly string[],
|
||||
laneIdsByMember: Readonly<Record<string, string>>
|
||||
): Record<string, string> {
|
||||
const result: Record<string, string> = {};
|
||||
for (const memberName of memberNames) {
|
||||
const laneId = laneIdForMember(memberName, laneIdsByMember);
|
||||
if (!laneId) continue;
|
||||
result[memberName] = laneId;
|
||||
const normalizedMemberName = normalizeMemberName(memberName);
|
||||
if (normalizedMemberName && normalizedMemberName !== memberName) {
|
||||
result[normalizedMemberName] = laneId;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getSafeGraphLogPreviewLaneId(
|
||||
member: ResolvedTeamMember | undefined
|
||||
): string | undefined {
|
||||
|
|
@ -226,10 +251,11 @@ export function useGraphMemberLogPreviews(input: {
|
|||
return;
|
||||
}
|
||||
|
||||
const requestedLaneIdsByMember = buildLaneIdsForMembers(membersToRequest, laneIdsByMember);
|
||||
const requestKey = buildRequestKey({
|
||||
teamName: input.teamName,
|
||||
memberNames: membersToRequest,
|
||||
laneIdsByMember,
|
||||
laneIdsByMember: requestedLaneIdsByMember,
|
||||
maxItemsPerMember,
|
||||
textLimit,
|
||||
forceRefresh: options?.forceRefresh,
|
||||
|
|
@ -247,7 +273,9 @@ export function useGraphMemberLogPreviews(input: {
|
|||
const requestOptions: MemberLogPreviewRequestOptions = {
|
||||
maxItemsPerMember,
|
||||
textLimit,
|
||||
...(Object.keys(laneIdsByMember).length > 0 ? { laneIdsByMember } : {}),
|
||||
...(Object.keys(requestedLaneIdsByMember).length > 0
|
||||
? { laneIdsByMember: requestedLaneIdsByMember }
|
||||
: {}),
|
||||
...(options?.forceRefresh ? { forceRefresh: true } : {}),
|
||||
};
|
||||
request = api.memberLogStream
|
||||
|
|
|
|||
|
|
@ -1601,11 +1601,7 @@ Reply to this comment using MCP tool task_add_comment.
|
|||
title: 'Bash result',
|
||||
preview: 'Tests passed',
|
||||
});
|
||||
expect(result.items[1]).toMatchObject({
|
||||
kind: 'tool_use',
|
||||
title: 'Bash',
|
||||
preview: 'pnpm test',
|
||||
});
|
||||
expect(result.items).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('does not label arbitrary message fields as sent messages', () => {
|
||||
|
|
|
|||
|
|
@ -533,6 +533,8 @@ function buildToolUseKey(input: {
|
|||
function isToolUseSupersededBySuccessResult(toolName: string): boolean {
|
||||
const canonical = canonicalToolName(toolName);
|
||||
return (
|
||||
canonical === 'bash' ||
|
||||
canonical === 'shell' ||
|
||||
canonical === 'sendmessage' ||
|
||||
canonical === 'message_send' ||
|
||||
canonical.startsWith('cross_team_') ||
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ describe('ClaudeMemberTranscriptPreviewSource', () => {
|
|||
const result = await source.loadPreview(previewInput({ textLimit: 160 }));
|
||||
|
||||
expect(result.status).toBe('included');
|
||||
expect(result.items.map((item) => item.kind)).toEqual(['tool_result', 'tool_use']);
|
||||
expect(result.items.map((item) => item.kind)).toEqual(['tool_result']);
|
||||
expect(result.items[0]?.preview?.length).toBeLessThanOrEqual(160);
|
||||
expect(parseFiles).toHaveBeenCalledWith(['/transcripts/latest.jsonl']);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -139,7 +139,10 @@ describe('useGraphMemberLogPreviews', () => {
|
|||
<HookProbe
|
||||
teamName="alpha-team"
|
||||
memberNames={['alice', 'alice']}
|
||||
laneIdsByMember={{ alice: 'secondary:opencode:alice' }}
|
||||
laneIdsByMember={{
|
||||
alice: 'secondary:opencode:alice',
|
||||
bob: 'secondary:opencode:bob',
|
||||
}}
|
||||
onState={() => undefined}
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue