show assistant icon search previews
This commit is contained in:
1 parent
59bed6b995
commit
6a98036c50
5 files changed
+214
-7
No files matched your search
@@ -27,6 +27,7 @@ const excludedKeys = new Set([
|
||||
]);
|
||||
const sensitiveKeyPattern = /(?:api.?key|authorization|cookie|credential|password|secret|token)/iu;
|
||||
const maximumItems = 6;
|
||||
const maximumIconItems = 8;
|
||||
const maximumFields = 6;
|
||||
|
||||
type ToolResultPrimitive = string | number | boolean;
|
||||
@@ -54,7 +55,19 @@ export interface ToolResultItem {
|
||||
fields: ToolResultField[];
|
||||
}
|
||||
|
||||
export interface ToolResultIconItem {
|
||||
name: string;
|
||||
url: string;
|
||||
repository?: string;
|
||||
variant: string;
|
||||
}
|
||||
|
||||
export type ToolResultPresentation =
|
||||
| {
|
||||
type: "icons";
|
||||
items: ToolResultIconItem[];
|
||||
totalCount: number;
|
||||
}
|
||||
| {
|
||||
type: "collection";
|
||||
items: ToolResultItem[];
|
||||
@@ -69,6 +82,10 @@ export type ToolResultPresentation =
|
||||
text: string;
|
||||
};
|
||||
|
||||
interface ToolResultPresentationOptions {
|
||||
toolName?: string;
|
||||
}
|
||||
|
||||
const asRecord = (value: unknown): Record<string, unknown> | undefined =>
|
||||
typeof value === "object" && value !== null && !Array.isArray(value) ? (value as Record<string, unknown>) : undefined;
|
||||
|
||||
@@ -148,7 +165,56 @@ const findCollection = (record: Record<string, unknown>) => {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const getToolResultPresentation = (result: unknown): ToolResultPresentation | undefined => {
|
||||
const getIconVariant = (name: string) => {
|
||||
const extension = name.slice(name.lastIndexOf(".") + 1).trim();
|
||||
return extension.length > 0 && extension !== name ? extension.toUpperCase() : "ICON";
|
||||
};
|
||||
|
||||
const getSafeIconUrl = (value: unknown) => {
|
||||
if (typeof value !== "string" || !URL.canParse(value)) return undefined;
|
||||
const url = new URL(value);
|
||||
if ((url.protocol !== "http:" && url.protocol !== "https:") || url.username || url.password) return undefined;
|
||||
return value;
|
||||
};
|
||||
|
||||
const getIconPresentation = (record: Record<string, unknown>): ToolResultPresentation | undefined => {
|
||||
const repositories = record.icons;
|
||||
if (!Array.isArray(repositories)) return undefined;
|
||||
|
||||
const isIconSearchResult =
|
||||
"countIcons" in record || repositories.some((value) => Array.isArray(asRecord(value)?.icons));
|
||||
if (!isIconSearchResult) return undefined;
|
||||
|
||||
const items = repositories.flatMap((value) => {
|
||||
const repository = asRecord(value);
|
||||
if (!repository || !Array.isArray(repository.icons)) return [];
|
||||
const repositoryName = toDisplayValue(repository.slug);
|
||||
|
||||
return repository.icons.flatMap((iconValue) => {
|
||||
const icon = asRecord(iconValue);
|
||||
if (!icon) return [];
|
||||
const name = toDisplayValue(icon.name);
|
||||
const url = getSafeIconUrl(icon.url);
|
||||
if (typeof name !== "string" || !url) return [];
|
||||
|
||||
return [
|
||||
{
|
||||
name,
|
||||
url,
|
||||
repository: typeof repositoryName === "string" ? repositoryName : undefined,
|
||||
variant: getIconVariant(name),
|
||||
},
|
||||
];
|
||||
});
|
||||
});
|
||||
|
||||
return { type: "icons", items: items.slice(0, maximumIconItems), totalCount: items.length };
|
||||
};
|
||||
|
||||
export const getToolResultPresentation = (
|
||||
result: unknown,
|
||||
options: ToolResultPresentationOptions = {},
|
||||
): ToolResultPresentation | undefined => {
|
||||
if (typeof result === "string") {
|
||||
const text = result.trim();
|
||||
if (text.length === 0) return undefined;
|
||||
@@ -156,6 +222,9 @@ export const getToolResultPresentation = (result: unknown): ToolResultPresentati
|
||||
}
|
||||
|
||||
const record = asRecord(result);
|
||||
const iconPresentation = record && options.toolName === "icon_findIcons" ? getIconPresentation(record) : undefined;
|
||||
if (iconPresentation) return iconPresentation;
|
||||
|
||||
const collection = Array.isArray(result) ? result : record ? findCollection(record) : undefined;
|
||||
if (collection) {
|
||||
const items = collection
|
||||
|
||||
Reference in new issue
Block a user