file-search.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import { createProviderToolFactoryWithOutputSchema } from "@ai-sdk/provider-utils"
  2. import type {
  3. OpenAIResponsesFileSearchToolComparisonFilter,
  4. OpenAIResponsesFileSearchToolCompoundFilter,
  5. } from "../openai-responses-api-types"
  6. import { z } from "zod/v4"
  7. const comparisonFilterSchema = z.object({
  8. key: z.string(),
  9. type: z.enum(["eq", "ne", "gt", "gte", "lt", "lte"]),
  10. value: z.union([z.string(), z.number(), z.boolean()]),
  11. })
  12. const compoundFilterSchema: z.ZodType<any> = z.object({
  13. type: z.enum(["and", "or"]),
  14. filters: z.array(z.union([comparisonFilterSchema, z.lazy(() => compoundFilterSchema)])),
  15. })
  16. export const fileSearchArgsSchema = z.object({
  17. vectorStoreIds: z.array(z.string()),
  18. maxNumResults: z.number().optional(),
  19. ranking: z
  20. .object({
  21. ranker: z.string().optional(),
  22. scoreThreshold: z.number().optional(),
  23. })
  24. .optional(),
  25. filters: z.union([comparisonFilterSchema, compoundFilterSchema]).optional(),
  26. })
  27. export const fileSearchOutputSchema = z.object({
  28. queries: z.array(z.string()),
  29. results: z
  30. .array(
  31. z.object({
  32. attributes: z.record(z.string(), z.unknown()),
  33. fileId: z.string(),
  34. filename: z.string(),
  35. score: z.number(),
  36. text: z.string(),
  37. }),
  38. )
  39. .nullable(),
  40. })
  41. export const fileSearch = createProviderToolFactoryWithOutputSchema<
  42. {},
  43. {
  44. /**
  45. * The search query to execute.
  46. */
  47. queries: string[]
  48. /**
  49. * The results of the file search tool call.
  50. */
  51. results:
  52. | null
  53. | {
  54. /**
  55. * Set of 16 key-value pairs that can be attached to an object.
  56. * This can be useful for storing additional information about the object
  57. * in a structured format, and querying for objects via API or the dashboard.
  58. * Keys are strings with a maximum length of 64 characters.
  59. * Values are strings with a maximum length of 512 characters, booleans, or numbers.
  60. */
  61. attributes: Record<string, unknown>
  62. /**
  63. * The unique ID of the file.
  64. */
  65. fileId: string
  66. /**
  67. * The name of the file.
  68. */
  69. filename: string
  70. /**
  71. * The relevance score of the file - a value between 0 and 1.
  72. */
  73. score: number
  74. /**
  75. * The text that was retrieved from the file.
  76. */
  77. text: string
  78. }[]
  79. },
  80. {
  81. /**
  82. * List of vector store IDs to search through.
  83. */
  84. vectorStoreIds: string[]
  85. /**
  86. * Maximum number of search results to return. Defaults to 10.
  87. */
  88. maxNumResults?: number
  89. /**
  90. * Ranking options for the search.
  91. */
  92. ranking?: {
  93. /**
  94. * The ranker to use for the file search.
  95. */
  96. ranker?: string
  97. /**
  98. * The score threshold for the file search, a number between 0 and 1.
  99. * Numbers closer to 1 will attempt to return only the most relevant results,
  100. * but may return fewer results.
  101. */
  102. scoreThreshold?: number
  103. }
  104. /**
  105. * A filter to apply.
  106. */
  107. filters?: OpenAIResponsesFileSearchToolComparisonFilter | OpenAIResponsesFileSearchToolCompoundFilter
  108. }
  109. >({
  110. id: "openai.file_search",
  111. inputSchema: z.object({}),
  112. outputSchema: fileSearchOutputSchema,
  113. })