jp_lit_refine_results
Refine saved Japanese literature search results locally: sort, filter, and perform set operations (union, intersection, minus) without re-searching upstream. Optionally retrieve duplicate clusters.
Instructions
保存済み jp_lit_search 結果を upstream 再検索せずローカルでソート・フィルタ・集合演算し、必要時だけ重複候補クラスタも返す
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| cache_key | No | ||
| cache_keys | No | ||
| session_id | No | ||
| combine | No | union | |
| key_by | No | source_record | |
| sort_by | No | ||
| sort_order | No | asc | |
| limit | No | ||
| offset | No | ||
| include_duplicate_clusters | No | ||
| cluster_limit | No | ||
| cluster_offset | No | ||
| cluster_member_limit | No | ||
| filters | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| base_cache_key | Yes | ||
| base_cache_keys | Yes | ||
| combine | Yes | ||
| key_by | Yes | ||
| totals_by_base | Yes | ||
| total_before | Yes | ||
| total_after | Yes | ||
| limit | Yes | ||
| offset | Yes | ||
| items | Yes | ||
| cluster_summary | No | ||
| clusters | No |
Implementation Reference
- src/tools/jpLitRefineResults.ts:225-297 (handler)Main handler function createJpLitRefineResultsTool - parses input, resolves cache keys, fetches cached search results, combines/filters/sorts items, builds duplicate clusters, and returns structured output
export function createJpLitRefineResultsTool( cache: FileCache, sessions: SessionStore ) { return async (input: unknown) => { const parsed = refineResultsInputSchema.parse(input); const cacheKeys = await resolveBaseCacheKeys(parsed, sessions); const cachedResults = await Promise.all( cacheKeys.map(async (cacheKey) => { const cached = await cache.read<SearchOutput>("jp_lit_search", cacheKey); if (!cached) { throw new Error(`cache_key=${cacheKey} のキャッシュが見つかりません`); } return { cache_key: cacheKey, items: cached.structured_content.items }; }) ); const combinedItems = combineItems( cachedResults.map((result) => result.items), parsed ); const filteredItems = applyFilters(combinedItems, parsed); const sortedItems = applySort(filteredItems, parsed); const slicedItems = sortedItems.slice(parsed.offset, parsed.offset + parsed.limit); const rawUnionClusterCandidates = applySort( applyFilters(cachedResults.flatMap((result) => result.items), parsed), parsed ); const clusterCandidates = parsed.combine === "union" ? rawUnionClusterCandidates : sortedItems; const clusterOutput = parsed.include_duplicate_clusters ? buildDuplicateClusters(clusterCandidates, { clusterLimit: parsed.cluster_limit, clusterOffset: parsed.cluster_offset, memberLimit: parsed.cluster_member_limit }) : null; const structuredContent: RefineResultsOutput = refineResultsOutputSchema.parse({ base_cache_key: cacheKeys[0], base_cache_keys: cacheKeys, combine: parsed.combine, key_by: parsed.key_by, totals_by_base: cachedResults.map((entry) => ({ cache_key: entry.cache_key, total: entry.items.length })), total_before: combinedItems.length, total_after: sortedItems.length, limit: parsed.limit, offset: parsed.offset, items: slicedItems, ...(clusterOutput ? { cluster_summary: clusterOutput.summary, clusters: clusterOutput.clusters } : {}) }); return { content: [ { type: "text" as const, text: JSON.stringify(structuredContent, null, 2) } ], structuredContent }; }; } - src/lib/schemas.ts:564-581 (schema)refineResultsInputSchema defines input params: cache_key, cache_keys, session_id, combine (union/intersection/minus), key_by, sort_by/order, limit/offset, include_duplicate_clusters, cluster_* config, and filters
export const refineResultsInputSchema = z.object({ cache_key: z.string().trim().min(1).optional(), cache_keys: z.array(z.string().trim().min(1)).min(1).optional(), session_id: z.string().trim().regex(/^\d{4}-\d{2}-\d{2}-\d{6}$/).optional(), combine: z.enum(["union", "intersection", "minus"]).default("union"), key_by: z .enum(["source_record", "duplicate_key", "title_author_year"]) .default("source_record"), sort_by: z.enum(["issued_at", "title"]).optional(), sort_order: z.enum(["asc", "desc"]).default("asc"), limit: z.number().int().positive().max(200).default(30), offset: z.number().int().nonnegative().default(0), include_duplicate_clusters: z.boolean().default(false), cluster_limit: z.number().int().positive().default(20), cluster_offset: z.number().int().nonnegative().default(0), cluster_member_limit: z.number().int().positive().default(5), filters: refineResultsFiltersSchema.optional() }); - src/lib/schemas.ts:583-601 (schema)refineResultsOutputSchema defines output shape: base_cache_key(s), totals_by_base, total_before/after, limit, offset, items, cluster_summary, clusters
export const refineResultsOutputSchema = z.object({ base_cache_key: z.string(), base_cache_keys: z.array(z.string()), combine: z.enum(["union", "intersection", "minus"]), key_by: z.enum(["source_record", "duplicate_key", "title_author_year"]), totals_by_base: z.array( z.object({ cache_key: z.string(), total: z.number().int().nonnegative() }) ), total_before: z.number().int().nonnegative(), total_after: z.number().int().nonnegative(), limit: z.number().int().positive(), offset: z.number().int().nonnegative(), items: z.array(searchItemSchema), cluster_summary: duplicateClusterSummarySchema.optional(), clusters: z.array(duplicateClusterSchema).optional() }); - src/lib/schemas.ts:514-522 (schema)refineResultsFiltersSchema defines filter fields: source, issued_from/to, online, digital_collection, title_contains, author_contains
const refineResultsFiltersSchema = z.object({ source: sourceSchema.optional(), issued_from: z.string().optional(), issued_to: z.string().optional(), online: z.boolean().optional(), digital_collection: z.boolean().optional(), title_contains: z.string().trim().min(1).optional(), author_contains: z.string().trim().min(1).optional() }); - src/server.ts:417-425 (registration)Registration of 'jp_lit_refine_results' tool in server.ts with description, input/output schemas, and handler
server.registerTool( "jp_lit_refine_results", { description: "保存済み jp_lit_search 結果を upstream 再検索せずローカルでソート・フィルタ・集合演算し、必要時だけ重複候補クラスタも返す", inputSchema: refineResultsInputSchema, outputSchema: refineResultsOutputSchema }, refineResultsTool );