UNPKG

@convex-dev/agent

Version:

A agent component for Convex.

315 lines 10.9 kB
import { v, } from "convex/values"; import { vVectorDimension } from "./component/vector/tables.js"; // const deprecated = v.optional(v.any()) as unknown as VNull<unknown, "optional">; export const vProviderOptions = v.record(v.string(), v.record(v.string(), v.any())); const providerOptions = v.optional(vProviderOptions); export const vProviderMetadata = vProviderOptions; const providerMetadata = providerOptions; export const vThreadStatus = v.union(v.literal("active"), v.literal("archived") // unused ); export const vMessageStatus = v.union(v.literal("pending"), v.literal("success"), v.literal("failed")); export const vRole = v.union(v.literal("system"), v.literal("user"), v.literal("assistant"), v.literal("tool")); export const vTextPart = v.object({ type: v.literal("text"), text: v.string(), providerOptions, }); export const vImagePart = v.object({ type: v.literal("image"), image: v.union(v.string(), v.bytes()), mimeType: v.optional(v.string()), providerOptions, }); export const vFilePart = v.object({ type: v.literal("file"), data: v.union(v.string(), v.bytes()), filename: v.optional(v.string()), mimeType: v.string(), providerOptions, }); export const vUserContent = v.union(v.string(), v.array(v.union(vTextPart, vImagePart, vFilePart))); export const vReasoningPart = v.object({ type: v.literal("reasoning"), text: v.string(), signature: v.optional(v.string()), providerOptions, }); export const vRedactedReasoningPart = v.object({ type: v.literal("redacted-reasoning"), data: v.string(), providerOptions, }); export const vReasoningDetails = v.array(v.union(v.object({ type: v.literal("text"), text: v.string(), signature: v.optional(v.string()), }), v.object({ type: v.literal("redacted"), data: v.string(), }))); export const vToolCallPart = v.object({ type: v.literal("tool-call"), toolCallId: v.string(), toolName: v.string(), args: v.any(), providerOptions, }); export const vAssistantContent = v.union(v.string(), v.array(v.union(vTextPart, vFilePart, vReasoningPart, vRedactedReasoningPart, vToolCallPart))); const vToolResultContent = v.array(v.union(v.object({ type: v.literal("text"), text: v.string(), }), v.object({ type: v.literal("image"), data: v.string(), mimeType: v.optional(v.string()), }))); const vToolResultPart = v.object({ type: v.literal("tool-result"), toolCallId: v.string(), toolName: v.string(), result: v.any(), // This is only here b/c steps include it in toolResults // Normal CoreMessage doesn't have this args: v.optional(v.any()), experimental_content: v.optional(vToolResultContent), isError: v.optional(v.boolean()), providerOptions, }); export const vToolContent = v.array(vToolResultPart); export const vContent = v.union(vUserContent, vAssistantContent, vToolContent); export const vUserMessage = v.object({ role: v.literal("user"), content: vUserContent, providerOptions, }); export const vAssistantMessage = v.object({ role: v.literal("assistant"), content: vAssistantContent, providerOptions, }); export const vToolMessage = v.object({ role: v.literal("tool"), content: vToolContent, providerOptions, }); export const vSystemMessage = v.object({ role: v.literal("system"), content: v.string(), providerOptions, }); export const vMessage = v.union(vUserMessage, vAssistantMessage, vToolMessage, vSystemMessage); export const vSource = v.object({ sourceType: v.literal("url"), id: v.string(), url: v.string(), title: v.optional(v.string()), providerOptions, }); export const vRequest = v.object({ body: v.optional(v.any()), // These are not usually present headers: v.optional(v.record(v.string(), v.string())), method: v.optional(v.string()), url: v.optional(v.string()), }); const vMessageWithFileAndId = v.object({ id: v.optional(v.string()), message: vMessage, fileId: v.optional(v.id("files")), }); export const vResponse = v.object({ id: v.string(), timestamp: v.number(), modelId: v.string(), headers: v.optional(v.record(v.string(), v.string())), // clear these? messages: v.array(vMessageWithFileAndId), body: v.optional(v.any()), }); export const vResponseWithoutMessages = v.object({ id: v.string(), timestamp: v.number(), modelId: v.string(), headers: v.optional(v.record(v.string(), v.string())), // clear these? body: v.optional(v.any()), }); export const vFinishReason = v.union(v.literal("stop"), v.literal("length"), v.literal("content-filter"), v.literal("tool-calls"), v.literal("error"), v.literal("other"), v.literal("unknown")); export const vUsage = v.object({ promptTokens: v.number(), completionTokens: v.number(), totalTokens: v.number(), }); export const vLanguageModelV1CallWarning = v.union(v.object({ type: v.literal("unsupported-setting"), setting: v.string(), details: v.optional(v.string()), }), v.object({ type: v.literal("unsupported-tool"), tool: v.any(), details: v.optional(v.string()), }), v.object({ type: v.literal("other"), message: v.string(), })); export const vMessageWithMetadataInternal = v.object({ id: v.optional(v.string()), // external id, e.g. from Vercel AI SDK message: vMessage, text: v.optional(v.string()), fileIds: v.optional(v.array(v.id("files"))), // metadata finishReason: v.optional(vFinishReason), model: v.optional(v.string()), provider: v.optional(v.string()), providerMetadata, sources: v.optional(v.array(vSource)), reasoning: v.optional(v.string()), reasoningDetails: v.optional(vReasoningDetails), usage: v.optional(vUsage), warnings: v.optional(v.array(vLanguageModelV1CallWarning)), error: v.optional(v.string()), }); export const vMessageWithMetadata = v.object({ ...vMessageWithMetadataInternal.fields, fileIds: v.optional(v.array(v.string())), }); export const vMessageEmbeddings = v.object({ model: v.string(), dimension: vVectorDimension, vectors: v.array(v.union(v.array(v.number()), v.null())), }); export const vObjectResult = v.object({ request: vRequest, response: vResponseWithoutMessages, finishReason: vFinishReason, usage: v.optional(v.any()), object: v.any(), error: v.optional(v.string()), warnings: v.optional(v.array(vLanguageModelV1CallWarning)), providerMetadata, }); export const vSearchOptions = v.object({ vector: v.optional(v.array(v.number())), vectorModel: v.optional(v.string()), text: v.optional(v.string()), limit: v.number(), vectorScoreThreshold: v.optional(v.number()), messageRange: v.optional(v.object({ before: v.number(), after: v.number() })), }); export const vContextOptionsSearchOptions = v.object({ limit: v.number(), textSearch: v.optional(v.boolean()), vectorSearch: v.optional(v.boolean()), messageRange: v.optional(v.object({ before: v.number(), after: v.number() })), }); export const vContextOptions = v.object({ excludeToolMessages: v.optional(v.boolean()), recentMessages: v.optional(v.number()), searchOptions: v.optional(vContextOptionsSearchOptions), searchOtherThreads: v.optional(v.boolean()), }); export const vStorageOptions = v.object({ saveMessages: v.optional(v.union(v.literal("all"), v.literal("none"), v.literal("promptAndOutput"))), }); const vStorageOptionsIncludingDeprecated = v.object({ ...vStorageOptions.fields, saveAllInputMessages: v.optional(v.boolean()), saveAnyInputMessages: v.optional(v.boolean()), saveOutputMessages: v.optional(v.boolean()), }); const vPromptFields = { system: v.optional(v.string()), prompt: v.optional(v.string()), messages: v.optional(v.array(vMessage)), promptMessageId: v.optional(v.string()), }; export const vCallSettingsFields = { maxTokens: v.optional(v.number()), temperature: v.optional(v.number()), topP: v.optional(v.number()), topK: v.optional(v.number()), presencePenalty: v.optional(v.number()), frequencyPenalty: v.optional(v.number()), seed: v.optional(v.number()), maxRetries: v.optional(v.number()), headers: v.optional(v.record(v.string(), v.string())), }; const vCommonArgs = { userId: v.optional(v.string()), threadId: v.optional(v.string()), contextOptions: v.optional(vContextOptions), storageOptions: v.optional(vStorageOptionsIncludingDeprecated), providerOptions, ...vCallSettingsFields, ...vPromptFields, }; export const vTextArgs = v.object({ ...vCommonArgs, stream: v.optional(v.boolean()), toolChoice: v.optional(v.union(v.literal("auto"), v.literal("none"), v.literal("required"), v.object({ type: v.literal("tool"), toolName: v.string(), }))), maxSteps: v.optional(v.number()), experimental_continueSteps: v.optional(v.boolean()), }); export const vSafeObjectArgs = v.object(vCommonArgs); export const vEmbeddingsWithMetadata = v.object({ vectors: v.array(v.union(v.array(v.number()), v.null())), dimension: vVectorDimension, model: v.string(), }); export function vPaginationResult(itemValidator) { return v.object({ page: v.array(itemValidator), continueCursor: v.string(), isDone: v.boolean(), splitCursor: v.optional(v.union(v.string(), v.null())), pageStatus: v.optional(v.union(v.literal("SplitRecommended"), v.literal("SplitRequired"), v.null())), }); } export const vTextStreamPart = v.union(v.object({ type: v.literal("text-delta"), textDelta: v.string(), }), v.object({ type: v.literal("reasoning"), textDelta: v.string(), }), v.object({ type: v.literal("source"), source: vSource, }), vToolCallPart, v.object({ type: v.literal("tool-call-streaming-start"), toolCallId: v.string(), toolName: v.string(), }), v.object({ type: v.literal("tool-call-delta"), toolCallId: v.string(), toolName: v.string(), argsTextDelta: v.string(), }), vToolResultPart); export const vStreamCursor = v.object({ streamId: v.string(), cursor: v.number(), }); export const vStreamArgs = v.optional(v.union(v.object({ kind: v.literal("list"), }), v.object({ kind: v.literal("deltas"), cursors: v.array(vStreamCursor), }))); export const vStreamMessage = v.object({ streamId: v.string(), order: v.number(), stepOrder: v.number(), // metadata userId: v.optional(v.string()), agentName: v.optional(v.string()), model: v.optional(v.string()), provider: v.optional(v.string()), providerOptions: v.optional(vProviderOptions), // Sent to model }); export const vStreamDelta = v.object({ streamId: v.string(), start: v.number(), // inclusive end: v.number(), // exclusive parts: v.array(vTextStreamPart), }); //# sourceMappingURL=validators.js.map