mirror of
https://github.com/meta-llama/llama-stack.git
synced 2025-06-27 18:50:41 +00:00
# What does this PR do? * Add responses list and detail views * Refactored components to be shared as much as possible between chat completions and responses ## Test Plan <img width="2014" alt="image" src="https://github.com/user-attachments/assets/6dee12ea-8876-4351-a6eb-2338058466ef" /> <img width="2021" alt="image" src="https://github.com/user-attachments/assets/6c7c71b8-25b7-4199-9c57-6960be5580c8" /> added tests
92 lines
2.5 KiB
TypeScript
92 lines
2.5 KiB
TypeScript
import { useMemo } from "react";
|
|
import {
|
|
isFunctionCallOutputItem,
|
|
AnyResponseItem,
|
|
FunctionCallOutputItem,
|
|
} from "../utils/item-types";
|
|
|
|
export interface GroupedItem {
|
|
item: AnyResponseItem;
|
|
index: number;
|
|
outputItem?: AnyResponseItem;
|
|
outputIndex?: number;
|
|
}
|
|
|
|
/**
|
|
* Hook to group function calls with their corresponding outputs
|
|
* @param items Array of items to group
|
|
* @returns Array of grouped items with their outputs
|
|
*/
|
|
export function useFunctionCallGrouping(
|
|
items: AnyResponseItem[],
|
|
): GroupedItem[] {
|
|
return useMemo(() => {
|
|
const groupedItems: GroupedItem[] = [];
|
|
const processedIndices = new Set<number>();
|
|
|
|
// Build a map of call_id to indices for function_call_output items
|
|
const callIdToIndices = new Map<string, number[]>();
|
|
|
|
for (let i = 0; i < items.length; i++) {
|
|
const item = items[i];
|
|
if (isFunctionCallOutputItem(item)) {
|
|
if (!callIdToIndices.has(item.call_id)) {
|
|
callIdToIndices.set(item.call_id, []);
|
|
}
|
|
callIdToIndices.get(item.call_id)!.push(i);
|
|
}
|
|
}
|
|
|
|
// Process items and group function calls with their outputs
|
|
for (let i = 0; i < items.length; i++) {
|
|
if (processedIndices.has(i)) {
|
|
continue;
|
|
}
|
|
|
|
const currentItem = items[i];
|
|
|
|
if (
|
|
currentItem.type === "function_call" &&
|
|
"name" in currentItem &&
|
|
"call_id" in currentItem
|
|
) {
|
|
const functionCallId = currentItem.call_id as string;
|
|
let outputIndex = -1;
|
|
let outputItem: FunctionCallOutputItem | null = null;
|
|
|
|
const relatedIndices = callIdToIndices.get(functionCallId) || [];
|
|
for (const idx of relatedIndices) {
|
|
const potentialOutput = items[idx];
|
|
outputIndex = idx;
|
|
outputItem = potentialOutput as FunctionCallOutputItem;
|
|
break;
|
|
}
|
|
|
|
if (outputItem && outputIndex !== -1) {
|
|
// Group function call with its function_call_output
|
|
groupedItems.push({
|
|
item: currentItem,
|
|
index: i,
|
|
outputItem,
|
|
outputIndex,
|
|
});
|
|
|
|
// Mark both items as processed
|
|
processedIndices.add(i);
|
|
processedIndices.add(outputIndex);
|
|
|
|
// Matching function call and output found, skip to next item
|
|
continue;
|
|
}
|
|
}
|
|
// render normally
|
|
groupedItems.push({
|
|
item: currentItem,
|
|
index: i,
|
|
});
|
|
processedIndices.add(i);
|
|
}
|
|
|
|
return groupedItems;
|
|
}, [items]);
|
|
}
|