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;
|
textLimit: number;
|
||||||
forceRefresh?: boolean;
|
forceRefresh?: boolean;
|
||||||
}): string {
|
}): string {
|
||||||
const laneEntries = Object.entries(input.laneIdsByMember)
|
const laneEntriesByMember = new Map<string, string>();
|
||||||
.map(([memberName, laneId]) => [normalizeMemberName(memberName), laneId.trim()] as const)
|
for (const [memberName, laneId] of Object.entries(input.laneIdsByMember)) {
|
||||||
.filter(([, laneId]) => laneId.length > 0)
|
const normalizedMemberName = normalizeMemberName(memberName);
|
||||||
.sort((left, right) => left[0].localeCompare(right[0]));
|
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([
|
return JSON.stringify([
|
||||||
input.teamName,
|
input.teamName,
|
||||||
input.memberNames.map(normalizeMemberName).sort((left, right) => left.localeCompare(right)),
|
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(
|
export function getSafeGraphLogPreviewLaneId(
|
||||||
member: ResolvedTeamMember | undefined
|
member: ResolvedTeamMember | undefined
|
||||||
): string | undefined {
|
): string | undefined {
|
||||||
|
|
@ -226,10 +251,11 @@ export function useGraphMemberLogPreviews(input: {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const requestedLaneIdsByMember = buildLaneIdsForMembers(membersToRequest, laneIdsByMember);
|
||||||
const requestKey = buildRequestKey({
|
const requestKey = buildRequestKey({
|
||||||
teamName: input.teamName,
|
teamName: input.teamName,
|
||||||
memberNames: membersToRequest,
|
memberNames: membersToRequest,
|
||||||
laneIdsByMember,
|
laneIdsByMember: requestedLaneIdsByMember,
|
||||||
maxItemsPerMember,
|
maxItemsPerMember,
|
||||||
textLimit,
|
textLimit,
|
||||||
forceRefresh: options?.forceRefresh,
|
forceRefresh: options?.forceRefresh,
|
||||||
|
|
@ -247,7 +273,9 @@ export function useGraphMemberLogPreviews(input: {
|
||||||
const requestOptions: MemberLogPreviewRequestOptions = {
|
const requestOptions: MemberLogPreviewRequestOptions = {
|
||||||
maxItemsPerMember,
|
maxItemsPerMember,
|
||||||
textLimit,
|
textLimit,
|
||||||
...(Object.keys(laneIdsByMember).length > 0 ? { laneIdsByMember } : {}),
|
...(Object.keys(requestedLaneIdsByMember).length > 0
|
||||||
|
? { laneIdsByMember: requestedLaneIdsByMember }
|
||||||
|
: {}),
|
||||||
...(options?.forceRefresh ? { forceRefresh: true } : {}),
|
...(options?.forceRefresh ? { forceRefresh: true } : {}),
|
||||||
};
|
};
|
||||||
request = api.memberLogStream
|
request = api.memberLogStream
|
||||||
|
|
|
||||||
|
|
@ -1601,11 +1601,7 @@ Reply to this comment using MCP tool task_add_comment.
|
||||||
title: 'Bash result',
|
title: 'Bash result',
|
||||||
preview: 'Tests passed',
|
preview: 'Tests passed',
|
||||||
});
|
});
|
||||||
expect(result.items[1]).toMatchObject({
|
expect(result.items).toHaveLength(1);
|
||||||
kind: 'tool_use',
|
|
||||||
title: 'Bash',
|
|
||||||
preview: 'pnpm test',
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not label arbitrary message fields as sent messages', () => {
|
it('does not label arbitrary message fields as sent messages', () => {
|
||||||
|
|
|
||||||
|
|
@ -533,6 +533,8 @@ function buildToolUseKey(input: {
|
||||||
function isToolUseSupersededBySuccessResult(toolName: string): boolean {
|
function isToolUseSupersededBySuccessResult(toolName: string): boolean {
|
||||||
const canonical = canonicalToolName(toolName);
|
const canonical = canonicalToolName(toolName);
|
||||||
return (
|
return (
|
||||||
|
canonical === 'bash' ||
|
||||||
|
canonical === 'shell' ||
|
||||||
canonical === 'sendmessage' ||
|
canonical === 'sendmessage' ||
|
||||||
canonical === 'message_send' ||
|
canonical === 'message_send' ||
|
||||||
canonical.startsWith('cross_team_') ||
|
canonical.startsWith('cross_team_') ||
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ describe('ClaudeMemberTranscriptPreviewSource', () => {
|
||||||
const result = await source.loadPreview(previewInput({ textLimit: 160 }));
|
const result = await source.loadPreview(previewInput({ textLimit: 160 }));
|
||||||
|
|
||||||
expect(result.status).toBe('included');
|
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(result.items[0]?.preview?.length).toBeLessThanOrEqual(160);
|
||||||
expect(parseFiles).toHaveBeenCalledWith(['/transcripts/latest.jsonl']);
|
expect(parseFiles).toHaveBeenCalledWith(['/transcripts/latest.jsonl']);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,10 @@ describe('useGraphMemberLogPreviews', () => {
|
||||||
<HookProbe
|
<HookProbe
|
||||||
teamName="alpha-team"
|
teamName="alpha-team"
|
||||||
memberNames={['alice', 'alice']}
|
memberNames={['alice', 'alice']}
|
||||||
laneIdsByMember={{ alice: 'secondary:opencode:alice' }}
|
laneIdsByMember={{
|
||||||
|
alice: 'secondary:opencode:alice',
|
||||||
|
bob: 'secondary:opencode:bob',
|
||||||
|
}}
|
||||||
onState={() => undefined}
|
onState={() => undefined}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue