diff --git a/genkit-tools/common/src/types/document.ts b/genkit-tools/common/src/types/document.ts index f84b802def..164cbc3920 100644 --- a/genkit-tools/common/src/types/document.ts +++ b/genkit-tools/common/src/types/document.ts @@ -14,159 +14,12 @@ * limitations under the License. */ import z from 'zod'; +import { MediaPartSchema, TextPartSchema } from './parts'; // // IMPORTANT: Keep this file in sync with genkit/ai/src/document.ts! // -const EmptyPartSchema = z.object({ - text: z.never().optional(), - media: z.never().optional(), - toolRequest: z.never().optional(), - toolResponse: z.never().optional(), - data: z.unknown().optional(), - metadata: z.record(z.unknown()).optional(), - custom: z.record(z.unknown()).optional(), - reasoning: z.never().optional(), - resource: z.never().optional(), -}); - -/** - * Zod schema for a text part. - */ -export const TextPartSchema = EmptyPartSchema.extend({ - /** The text of the document. */ - text: z.string(), -}); - -/** - * Text part. - */ -export type TextPart = z.infer; - -/** - * Zod schema for a reasoning part. - */ -export const ReasoningPartSchema = EmptyPartSchema.extend({ - /** The reasoning text of the message. */ - reasoning: z.string(), -}); - -/** - * Reasoning part. - */ -export type ReasoningPart = z.infer; - -/** - * Zod schema of media. - */ -export const MediaSchema = z.object({ - /** The media content type. Inferred from data uri if not provided. */ - contentType: z.string().optional(), - /** A `data:` or `https:` uri containing the media content. */ - url: z.string(), -}); - -/** - * Zod schema of a media part. - */ -export const MediaPartSchema = EmptyPartSchema.extend({ - media: MediaSchema, -}); - -/** - * Media part. - */ -export type MediaPart = z.infer; - -/** - * Zod schema of a tool request. - */ -export const ToolRequestSchema = z.object({ - /** The call id or reference for a specific request. */ - ref: z.string().optional(), - /** The name of the tool to call. */ - name: z.string(), - /** The input parameters for the tool, usually a JSON object. */ - input: z.unknown().optional(), -}); - -/** - * Zod schema of a tool request part. - */ -export const ToolRequestPartSchema = EmptyPartSchema.extend({ - /** A request for a tool to be executed, usually provided by a model. */ - toolRequest: ToolRequestSchema, -}); - -/** - * Tool part. - */ -export type ToolRequestPart = z.infer; - -/** - * Zod schema of a tool response. - */ -export const ToolResponseSchema = z.object({ - /** The call id or reference for a specific request. */ - ref: z.string().optional(), - /** The name of the tool. */ - name: z.string(), - /** The output data returned from the tool, usually a JSON object. */ - output: z.unknown().optional(), -}); - -/** - * Zod schema of a tool response part. - */ -export const ToolResponsePartSchema = EmptyPartSchema.extend({ - /** A provided response to a tool call. */ - toolResponse: ToolResponseSchema, -}); - -/** - * Tool response part. - */ -export type ToolResponsePart = z.infer; - -/** - * Zod schema of a data part. - */ -export const DataPartSchema = EmptyPartSchema.extend({ - data: z.unknown(), -}); - -/** - * Data part. - */ -export type DataPart = z.infer; - -/** - * Zod schema of a custom part. - */ -export const CustomPartSchema = EmptyPartSchema.extend({ - custom: z.record(z.any()), -}); - -/** - * Custom part. - */ -export type CustomPart = z.infer; - -/** - * Zod schema of a resource part. - */ -export const ResourcePartSchema = EmptyPartSchema.extend({ - resource: z.object({ - uri: z.string(), - }), -}); - -/** - * Resource part. - */ -export type ResourcePart = z.infer; - // Disclaimer: genkit/js/ai/document.ts defines the following schema, type pair // as PartSchema and Part, respectively. genkit-tools cannot retain those names // due to it clashing with similar schema in model.ts, and genkit-tools diff --git a/genkit-tools/common/src/types/model.ts b/genkit-tools/common/src/types/model.ts index 617d914383..9402fe9562 100644 --- a/genkit-tools/common/src/types/model.ts +++ b/genkit-tools/common/src/types/model.ts @@ -14,11 +14,12 @@ * limitations under the License. */ import { z } from 'zod'; +import { DocumentDataSchema } from './document'; import { CustomPartSchema, DataPartSchema, - DocumentDataSchema, MediaPartSchema, + PartSchema, ReasoningPartSchema, ResourcePartSchema, TextPartSchema, @@ -27,16 +28,18 @@ import { type CustomPart, type DataPart, type MediaPart, + type Part, type ReasoningPart, type ResourcePart, type TextPart, type ToolRequestPart, type ToolResponsePart, -} from './document'; +} from './parts'; export { CustomPartSchema, DataPartSchema, MediaPartSchema, + PartSchema, ReasoningPartSchema, ResourcePartSchema, TextPartSchema, @@ -45,6 +48,7 @@ export { type CustomPart, type DataPart, type MediaPart, + type Part, type ReasoningPart, type ResourcePart, type TextPart, @@ -73,25 +77,6 @@ export const OperationSchema = z.object({ */ export type OperationData = z.infer; -/** - * Zod schema of message part. - */ -export const PartSchema = z.union([ - TextPartSchema, - MediaPartSchema, - ToolRequestPartSchema, - ToolResponsePartSchema, - DataPartSchema, - CustomPartSchema, - ReasoningPartSchema, - ResourcePartSchema, -]); - -/** - * Message part. - */ -export type Part = z.infer; - /** * Zod schema of a message role. */ diff --git a/genkit-tools/common/src/types/parts.ts b/genkit-tools/common/src/types/parts.ts new file mode 100644 index 0000000000..d05d4c3553 --- /dev/null +++ b/genkit-tools/common/src/types/parts.ts @@ -0,0 +1,191 @@ +/** + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { z } from 'zod'; + +const EmptyPartSchema = z.object({ + text: z.never().optional(), + media: z.never().optional(), + toolRequest: z.never().optional(), + toolResponse: z.never().optional(), + data: z.unknown().optional(), + metadata: z.record(z.unknown()).optional(), + custom: z.record(z.unknown()).optional(), + reasoning: z.never().optional(), + resource: z.never().optional(), +}); + +/** + * Zod schema for a text part. + */ +export const TextPartSchema = EmptyPartSchema.extend({ + /** The text of the document. */ + text: z.string(), +}); + +/** + * Text part. + */ +export type TextPart = z.infer; + +/** + * Zod schema for a reasoning part. + */ +export const ReasoningPartSchema = EmptyPartSchema.extend({ + /** The reasoning text of the message. */ + reasoning: z.string(), +}); + +/** + * Reasoning part. + */ +export type ReasoningPart = z.infer; + +/** + * Zod schema of media. + */ +export const MediaSchema = z.object({ + /** The media content type. Inferred from data uri if not provided. */ + contentType: z.string().optional(), + /** A `data:` or `https:` uri containing the media content. */ + url: z.string(), +}); + +/** + * Zod schema of a media part. + */ +export const MediaPartSchema = EmptyPartSchema.extend({ + media: MediaSchema, +}); + +/** + * Media part. + */ +export type MediaPart = z.infer; + +/** + * Zod schema of a tool request. + */ +export const ToolRequestSchema = z.object({ + /** The call id or reference for a specific request. */ + ref: z.string().optional(), + /** The name of the tool to call. */ + name: z.string(), + /** The input parameters for the tool, usually a JSON object. */ + input: z.unknown().optional(), +}); + +/** + * Zod schema of a tool request part. + */ +export const ToolRequestPartSchema = EmptyPartSchema.extend({ + /** A request for a tool to be executed, usually provided by a model. */ + toolRequest: ToolRequestSchema, +}); + +/** + * Tool part. + */ +export type ToolRequestPart = z.infer; + +const ToolResponseSchemaBase = z.object({ + /** The call id or reference for a specific request. */ + ref: z.string().optional(), + /** The name of the tool. */ + name: z.string(), + /** The output data returned from the tool, usually a JSON object. */ + output: z.unknown().optional(), + payloadStrategy: z.enum(['both', 'fallback']).optional(), // default: both +}); + +/** + * Tool response part. + */ +export type ToolResponsePart = z.infer & { + content?: Part[]; +}; + +export const ToolResponseSchema: z.ZodType = + ToolResponseSchemaBase.extend({ + content: z.array(z.any()).optional(), + // TODO: switch to this once we have effective recursive schema support across the board. + // content: z.array(z.lazy(() => PartSchema)).optional(), + }); + +/** + * Zod schema of a tool response part. + */ +export const ToolResponsePartSchema = EmptyPartSchema.extend({ + /** A provided response to a tool call. */ + toolResponse: ToolResponseSchema, +}); + +/** + * Zod schema of a data part. + */ +export const DataPartSchema = EmptyPartSchema.extend({ + data: z.unknown(), +}); + +/** + * Data part. + */ +export type DataPart = z.infer; + +/** + * Zod schema of a custom part. + */ +export const CustomPartSchema = EmptyPartSchema.extend({ + custom: z.record(z.any()), +}); + +/** + * Custom part. + */ +export type CustomPart = z.infer; + +/** + * Zod schema of a resource part. + */ +export const ResourcePartSchema = EmptyPartSchema.extend({ + resource: z.object({ + uri: z.string(), + }), +}); + +/** + * Resource part. + */ +export type ResourcePart = z.infer; + +/** + * Zod schema of message part. + */ +export const PartSchema = z.union([ + TextPartSchema, + MediaPartSchema, + ToolRequestPartSchema, + ToolResponsePartSchema, + DataPartSchema, + CustomPartSchema, + ReasoningPartSchema, + ResourcePartSchema, +]); + +/** + * Message part. + */ +export type Part = z.infer; diff --git a/genkit-tools/genkit-schema.json b/genkit-tools/genkit-schema.json index 8a937f7c41..02c5e63136 100644 --- a/genkit-tools/genkit-schema.json +++ b/genkit-tools/genkit-schema.json @@ -1,74 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "$defs": { - "CustomPart": { - "type": "object", - "properties": { - "text": { - "not": {} - }, - "media": { - "not": {} - }, - "toolRequest": { - "not": {} - }, - "toolResponse": { - "not": {} - }, - "data": {}, - "metadata": { - "type": "object", - "additionalProperties": {} - }, - "custom": { - "type": "object", - "additionalProperties": {} - }, - "reasoning": { - "not": {} - }, - "resource": { - "not": {} - } - }, - "required": [ - "custom" - ], - "additionalProperties": false - }, - "DataPart": { - "type": "object", - "properties": { - "text": { - "$ref": "#/$defs/CustomPart/properties/text" - }, - "media": { - "$ref": "#/$defs/CustomPart/properties/media" - }, - "toolRequest": { - "$ref": "#/$defs/CustomPart/properties/toolRequest" - }, - "toolResponse": { - "$ref": "#/$defs/CustomPart/properties/toolResponse" - }, - "data": {}, - "metadata": { - "$ref": "#/$defs/CustomPart/properties/metadata" - }, - "custom": { - "type": "object", - "additionalProperties": {} - }, - "reasoning": { - "$ref": "#/$defs/CustomPart/properties/reasoning" - }, - "resource": { - "$ref": "#/$defs/CustomPart/properties/resource" - } - }, - "additionalProperties": false - }, "DocumentData": { "type": "object", "properties": { @@ -98,278 +30,6 @@ } ] }, - "MediaPart": { - "type": "object", - "properties": { - "text": { - "$ref": "#/$defs/CustomPart/properties/text" - }, - "media": { - "$ref": "#/$defs/Media" - }, - "toolRequest": { - "$ref": "#/$defs/CustomPart/properties/toolRequest" - }, - "toolResponse": { - "$ref": "#/$defs/CustomPart/properties/toolResponse" - }, - "data": { - "$ref": "#/$defs/CustomPart/properties/data" - }, - "metadata": { - "$ref": "#/$defs/CustomPart/properties/metadata" - }, - "custom": { - "$ref": "#/$defs/DataPart/properties/custom" - }, - "reasoning": { - "$ref": "#/$defs/CustomPart/properties/reasoning" - }, - "resource": { - "$ref": "#/$defs/CustomPart/properties/resource" - } - }, - "required": [ - "media" - ], - "additionalProperties": false - }, - "Media": { - "type": "object", - "properties": { - "contentType": { - "type": "string" - }, - "url": { - "type": "string" - } - }, - "required": [ - "url" - ], - "additionalProperties": false - }, - "ReasoningPart": { - "type": "object", - "properties": { - "text": { - "$ref": "#/$defs/CustomPart/properties/text" - }, - "media": { - "$ref": "#/$defs/CustomPart/properties/media" - }, - "toolRequest": { - "$ref": "#/$defs/CustomPart/properties/toolRequest" - }, - "toolResponse": { - "$ref": "#/$defs/CustomPart/properties/toolResponse" - }, - "data": { - "$ref": "#/$defs/CustomPart/properties/data" - }, - "metadata": { - "$ref": "#/$defs/CustomPart/properties/metadata" - }, - "custom": { - "$ref": "#/$defs/DataPart/properties/custom" - }, - "reasoning": { - "type": "string" - }, - "resource": { - "$ref": "#/$defs/CustomPart/properties/resource" - } - }, - "required": [ - "reasoning" - ], - "additionalProperties": false - }, - "ResourcePart": { - "type": "object", - "properties": { - "text": { - "$ref": "#/$defs/CustomPart/properties/text" - }, - "media": { - "$ref": "#/$defs/CustomPart/properties/media" - }, - "toolRequest": { - "$ref": "#/$defs/CustomPart/properties/toolRequest" - }, - "toolResponse": { - "$ref": "#/$defs/CustomPart/properties/toolResponse" - }, - "data": { - "$ref": "#/$defs/CustomPart/properties/data" - }, - "metadata": { - "$ref": "#/$defs/CustomPart/properties/metadata" - }, - "custom": { - "$ref": "#/$defs/DataPart/properties/custom" - }, - "reasoning": { - "$ref": "#/$defs/CustomPart/properties/reasoning" - }, - "resource": { - "type": "object", - "properties": { - "uri": { - "type": "string" - } - }, - "required": [ - "uri" - ], - "additionalProperties": false - } - }, - "required": [ - "resource" - ], - "additionalProperties": false - }, - "TextPart": { - "type": "object", - "properties": { - "text": { - "type": "string" - }, - "media": { - "$ref": "#/$defs/CustomPart/properties/media" - }, - "toolRequest": { - "$ref": "#/$defs/CustomPart/properties/toolRequest" - }, - "toolResponse": { - "$ref": "#/$defs/CustomPart/properties/toolResponse" - }, - "data": { - "$ref": "#/$defs/CustomPart/properties/data" - }, - "metadata": { - "$ref": "#/$defs/CustomPart/properties/metadata" - }, - "custom": { - "$ref": "#/$defs/DataPart/properties/custom" - }, - "reasoning": { - "$ref": "#/$defs/CustomPart/properties/reasoning" - }, - "resource": { - "$ref": "#/$defs/CustomPart/properties/resource" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - }, - "ToolRequestPart": { - "type": "object", - "properties": { - "text": { - "$ref": "#/$defs/CustomPart/properties/text" - }, - "media": { - "$ref": "#/$defs/CustomPart/properties/media" - }, - "toolRequest": { - "$ref": "#/$defs/ToolRequest" - }, - "toolResponse": { - "$ref": "#/$defs/CustomPart/properties/toolResponse" - }, - "data": { - "$ref": "#/$defs/CustomPart/properties/data" - }, - "metadata": { - "$ref": "#/$defs/CustomPart/properties/metadata" - }, - "custom": { - "$ref": "#/$defs/DataPart/properties/custom" - }, - "reasoning": { - "$ref": "#/$defs/CustomPart/properties/reasoning" - }, - "resource": { - "$ref": "#/$defs/CustomPart/properties/resource" - } - }, - "required": [ - "toolRequest" - ], - "additionalProperties": false - }, - "ToolRequest": { - "type": "object", - "properties": { - "ref": { - "type": "string" - }, - "name": { - "type": "string" - }, - "input": {} - }, - "required": [ - "name" - ], - "additionalProperties": false - }, - "ToolResponsePart": { - "type": "object", - "properties": { - "text": { - "$ref": "#/$defs/CustomPart/properties/text" - }, - "media": { - "$ref": "#/$defs/CustomPart/properties/media" - }, - "toolRequest": { - "$ref": "#/$defs/CustomPart/properties/toolRequest" - }, - "toolResponse": { - "$ref": "#/$defs/ToolResponse" - }, - "data": { - "$ref": "#/$defs/CustomPart/properties/data" - }, - "metadata": { - "$ref": "#/$defs/CustomPart/properties/metadata" - }, - "custom": { - "$ref": "#/$defs/DataPart/properties/custom" - }, - "reasoning": { - "$ref": "#/$defs/CustomPart/properties/reasoning" - }, - "resource": { - "$ref": "#/$defs/CustomPart/properties/resource" - } - }, - "required": [ - "toolResponse" - ], - "additionalProperties": false - }, - "ToolResponse": { - "type": "object", - "properties": { - "ref": { - "type": "string" - }, - "name": { - "type": "string" - }, - "output": {} - }, - "required": [ - "name" - ], - "additionalProperties": false - }, "EmbedRequest": { "type": "object", "properties": { @@ -661,6 +321,74 @@ ], "additionalProperties": false }, + "CustomPart": { + "type": "object", + "properties": { + "text": { + "not": {} + }, + "media": { + "not": {} + }, + "toolRequest": { + "not": {} + }, + "toolResponse": { + "not": {} + }, + "data": {}, + "metadata": { + "type": "object", + "additionalProperties": {} + }, + "custom": { + "type": "object", + "additionalProperties": {} + }, + "reasoning": { + "not": {} + }, + "resource": { + "not": {} + } + }, + "required": [ + "custom" + ], + "additionalProperties": false + }, + "DataPart": { + "type": "object", + "properties": { + "text": { + "$ref": "#/$defs/CustomPart/properties/text" + }, + "media": { + "$ref": "#/$defs/CustomPart/properties/media" + }, + "toolRequest": { + "$ref": "#/$defs/CustomPart/properties/toolRequest" + }, + "toolResponse": { + "$ref": "#/$defs/CustomPart/properties/toolResponse" + }, + "data": {}, + "metadata": { + "$ref": "#/$defs/CustomPart/properties/metadata" + }, + "custom": { + "type": "object", + "additionalProperties": {} + }, + "reasoning": { + "$ref": "#/$defs/CustomPart/properties/reasoning" + }, + "resource": { + "$ref": "#/$defs/CustomPart/properties/resource" + } + }, + "additionalProperties": false + }, "FinishReason": { "type": "string", "enum": [ @@ -939,13 +667,49 @@ "type": "number" } }, - "thoughtsTokens": { - "type": "number" + "thoughtsTokens": { + "type": "number" + }, + "cachedContentTokens": { + "type": "number" + } + }, + "additionalProperties": false + }, + "MediaPart": { + "type": "object", + "properties": { + "text": { + "$ref": "#/$defs/CustomPart/properties/text" + }, + "media": { + "$ref": "#/$defs/Media" + }, + "toolRequest": { + "$ref": "#/$defs/CustomPart/properties/toolRequest" + }, + "toolResponse": { + "$ref": "#/$defs/CustomPart/properties/toolResponse" + }, + "data": { + "$ref": "#/$defs/CustomPart/properties/data" + }, + "metadata": { + "$ref": "#/$defs/CustomPart/properties/metadata" + }, + "custom": { + "$ref": "#/$defs/DataPart/properties/custom" }, - "cachedContentTokens": { - "type": "number" + "reasoning": { + "$ref": "#/$defs/CustomPart/properties/reasoning" + }, + "resource": { + "$ref": "#/$defs/CustomPart/properties/resource" } }, + "required": [ + "media" + ], "additionalProperties": false }, "Message": { @@ -1213,6 +977,87 @@ } ] }, + "ReasoningPart": { + "type": "object", + "properties": { + "text": { + "$ref": "#/$defs/CustomPart/properties/text" + }, + "media": { + "$ref": "#/$defs/CustomPart/properties/media" + }, + "toolRequest": { + "$ref": "#/$defs/CustomPart/properties/toolRequest" + }, + "toolResponse": { + "$ref": "#/$defs/CustomPart/properties/toolResponse" + }, + "data": { + "$ref": "#/$defs/CustomPart/properties/data" + }, + "metadata": { + "$ref": "#/$defs/CustomPart/properties/metadata" + }, + "custom": { + "$ref": "#/$defs/DataPart/properties/custom" + }, + "reasoning": { + "type": "string" + }, + "resource": { + "$ref": "#/$defs/CustomPart/properties/resource" + } + }, + "required": [ + "reasoning" + ], + "additionalProperties": false + }, + "ResourcePart": { + "type": "object", + "properties": { + "text": { + "$ref": "#/$defs/CustomPart/properties/text" + }, + "media": { + "$ref": "#/$defs/CustomPart/properties/media" + }, + "toolRequest": { + "$ref": "#/$defs/CustomPart/properties/toolRequest" + }, + "toolResponse": { + "$ref": "#/$defs/CustomPart/properties/toolResponse" + }, + "data": { + "$ref": "#/$defs/CustomPart/properties/data" + }, + "metadata": { + "$ref": "#/$defs/CustomPart/properties/metadata" + }, + "custom": { + "$ref": "#/$defs/DataPart/properties/custom" + }, + "reasoning": { + "$ref": "#/$defs/CustomPart/properties/reasoning" + }, + "resource": { + "type": "object", + "properties": { + "uri": { + "type": "string" + } + }, + "required": [ + "uri" + ], + "additionalProperties": false + } + }, + "required": [ + "resource" + ], + "additionalProperties": false + }, "Role": { "type": "string", "enum": [ @@ -1222,6 +1067,42 @@ "tool" ] }, + "TextPart": { + "type": "object", + "properties": { + "text": { + "type": "string" + }, + "media": { + "$ref": "#/$defs/CustomPart/properties/media" + }, + "toolRequest": { + "$ref": "#/$defs/CustomPart/properties/toolRequest" + }, + "toolResponse": { + "$ref": "#/$defs/CustomPart/properties/toolResponse" + }, + "data": { + "$ref": "#/$defs/CustomPart/properties/data" + }, + "metadata": { + "$ref": "#/$defs/CustomPart/properties/metadata" + }, + "custom": { + "$ref": "#/$defs/DataPart/properties/custom" + }, + "reasoning": { + "$ref": "#/$defs/CustomPart/properties/reasoning" + }, + "resource": { + "$ref": "#/$defs/CustomPart/properties/resource" + } + }, + "required": [ + "text" + ], + "additionalProperties": false + }, "ToolDefinition": { "type": "object", "properties": { @@ -1269,6 +1150,135 @@ ], "additionalProperties": false }, + "ToolRequestPart": { + "type": "object", + "properties": { + "text": { + "$ref": "#/$defs/CustomPart/properties/text" + }, + "media": { + "$ref": "#/$defs/CustomPart/properties/media" + }, + "toolRequest": { + "$ref": "#/$defs/ToolRequest" + }, + "toolResponse": { + "$ref": "#/$defs/CustomPart/properties/toolResponse" + }, + "data": { + "$ref": "#/$defs/CustomPart/properties/data" + }, + "metadata": { + "$ref": "#/$defs/CustomPart/properties/metadata" + }, + "custom": { + "$ref": "#/$defs/DataPart/properties/custom" + }, + "reasoning": { + "$ref": "#/$defs/CustomPart/properties/reasoning" + }, + "resource": { + "$ref": "#/$defs/CustomPart/properties/resource" + } + }, + "required": [ + "toolRequest" + ], + "additionalProperties": false + }, + "ToolResponsePart": { + "type": "object", + "properties": { + "text": { + "$ref": "#/$defs/CustomPart/properties/text" + }, + "media": { + "$ref": "#/$defs/CustomPart/properties/media" + }, + "toolRequest": { + "$ref": "#/$defs/CustomPart/properties/toolRequest" + }, + "toolResponse": { + "$ref": "#/$defs/ToolResponse" + }, + "data": { + "$ref": "#/$defs/CustomPart/properties/data" + }, + "metadata": { + "$ref": "#/$defs/CustomPart/properties/metadata" + }, + "custom": { + "$ref": "#/$defs/DataPart/properties/custom" + }, + "reasoning": { + "$ref": "#/$defs/CustomPart/properties/reasoning" + }, + "resource": { + "$ref": "#/$defs/CustomPart/properties/resource" + } + }, + "required": [ + "toolResponse" + ], + "additionalProperties": false + }, + "Media": { + "type": "object", + "properties": { + "contentType": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "required": [ + "url" + ], + "additionalProperties": false + }, + "ToolRequest": { + "type": "object", + "properties": { + "ref": { + "type": "string" + }, + "name": { + "type": "string" + }, + "input": {} + }, + "required": [ + "name" + ], + "additionalProperties": false + }, + "ToolResponse": { + "type": "object", + "properties": { + "ref": { + "type": "string" + }, + "name": { + "type": "string" + }, + "output": {}, + "payloadStrategy": { + "type": "string", + "enum": [ + "both", + "fallback" + ] + }, + "content": { + "type": "array" + } + }, + "required": [ + "name" + ], + "additionalProperties": false + }, "CommonRerankerOptions": { "type": "object", "properties": { diff --git a/genkit-tools/scripts/schema-exporter.ts b/genkit-tools/scripts/schema-exporter.ts index 78f310b071..48df79b56a 100644 --- a/genkit-tools/scripts/schema-exporter.ts +++ b/genkit-tools/scripts/schema-exporter.ts @@ -27,6 +27,7 @@ const EXPORTED_TYPE_MODULES = [ '../common/src/types/evaluator.ts', '../common/src/types/error.ts', '../common/src/types/model.ts', + '../common/src/types/parts.ts', '../common/src/types/reranker.ts', '../common/src/types/retriever.ts', '../common/src/types/trace.ts', diff --git a/go/ai/gen.go b/go/ai/gen.go index 5d24d51bf0..5b39121259 100644 --- a/go/ai/gen.go +++ b/go/ai/gen.go @@ -390,11 +390,13 @@ type toolRequestPart struct { // the results of running a specific tool on the arguments passed to the client // by the model in a [ToolRequest]. type ToolResponse struct { - Name string `json:"name,omitempty"` + Content []any `json:"content,omitempty"` + Name string `json:"name,omitempty"` // Output is a JSON object describing the results of running the tool. // An example might be map[string]any{"name":"Thomas Jefferson", "born":1743}. - Output any `json:"output,omitempty"` - Ref string `json:"ref,omitempty"` + Output any `json:"output,omitempty"` + PayloadStrategy ToolResponsePayloadStrategy `json:"payloadStrategy,omitempty"` + Ref string `json:"ref,omitempty"` } type toolResponsePart struct { @@ -402,6 +404,13 @@ type toolResponsePart struct { ToolResponse *ToolResponse `json:"toolResponse,omitempty"` } +type ToolResponsePayloadStrategy string + +const ( + ToolResponsePayloadStrategyBoth ToolResponsePayloadStrategy = "both" + ToolResponsePayloadStrategyFallback ToolResponsePayloadStrategy = "fallback" +) + type TraceMetadata struct { FeatureName string `json:"featureName,omitempty"` Paths []*PathMetadata `json:"paths,omitempty"` diff --git a/go/internal/cmd/jsonschemagen/jsonschemagen.go b/go/internal/cmd/jsonschemagen/jsonschemagen.go index 6714c0dce8..243346f5e4 100644 --- a/go/internal/cmd/jsonschemagen/jsonschemagen.go +++ b/go/internal/cmd/jsonschemagen/jsonschemagen.go @@ -454,6 +454,9 @@ func (g *generator) generateDoc(s *Schema, ic *itemConfig) { // typeExpr returns a Go type expression denoting the type represented by the schema. func (g *generator) typeExpr(s *Schema) (string, error) { // A reference to another type refers to that type by name. Use the name. + if s == nil { + return "any", nil + } if s.Ref != "" { name, ok := strings.CutPrefix(s.Ref, refPrefix) if !ok { diff --git a/js/ai/src/document.ts b/js/ai/src/document.ts index c539f83fc3..67a03fd3ca 100644 --- a/js/ai/src/document.ts +++ b/js/ai/src/document.ts @@ -15,155 +15,8 @@ */ import { z } from '@genkit-ai/core'; -import type { Embedding } from './embedder'; - -const EmptyPartSchema = z.object({ - text: z.never().optional(), - media: z.never().optional(), - toolRequest: z.never().optional(), - toolResponse: z.never().optional(), - data: z.unknown().optional(), - metadata: z.record(z.unknown()).optional(), - custom: z.record(z.unknown()).optional(), - reasoning: z.never().optional(), - resource: z.never().optional(), -}); - -/** - * Zod schema for a text part. - */ -export const TextPartSchema = EmptyPartSchema.extend({ - /** The text of the message. */ - text: z.string(), -}); - -/** - * Zod schema for a reasoning part. - */ -export const ReasoningPartSchema = EmptyPartSchema.extend({ - /** The reasoning text of the message. */ - reasoning: z.string(), -}); - -/** - * Text part. - */ -export type TextPart = z.infer; - -/** - * Zod schema of media. - */ -export const MediaSchema = z.object({ - /** The media content type. Inferred from data uri if not provided. */ - contentType: z.string().optional(), - /** A `data:` or `https:` uri containing the media content. */ - url: z.string(), -}); - -/** - * Zod schema of a media part. - */ -export const MediaPartSchema = EmptyPartSchema.extend({ - media: MediaSchema, -}); - -/** - * Media part. - */ -export type MediaPart = z.infer; - -/** - * Zod schema of a tool request. - */ -export const ToolRequestSchema = z.object({ - /** The call id or reference for a specific request. */ - ref: z.string().optional(), - /** The name of the tool to call. */ - name: z.string(), - /** The input parameters for the tool, usually a JSON object. */ - input: z.unknown().optional(), -}); -export type ToolRequest = z.infer; - -/** - * Zod schema of a tool request part. - */ -export const ToolRequestPartSchema = EmptyPartSchema.extend({ - /** A request for a tool to be executed, usually provided by a model. */ - toolRequest: ToolRequestSchema, -}); - -/** - * Tool part. - */ -export type ToolRequestPart = z.infer; - -/** - * Zod schema of a tool response. - */ -export const ToolResponseSchema = z.object({ - /** The call id or reference for a specific request. */ - ref: z.string().optional(), - /** The name of the tool. */ - name: z.string(), - /** The output data returned from the tool, usually a JSON object. */ - output: z.unknown().optional(), -}); -export type ToolResponse = z.infer; - -/** - * Zod schema of a tool response part. - */ -export const ToolResponsePartSchema = EmptyPartSchema.extend({ - /** A provided response to a tool call. */ - toolResponse: ToolResponseSchema, -}); - -/** - * Tool response part. - */ -export type ToolResponsePart = z.infer; - -/** - * Zod schema of a data part. - */ -export const DataPartSchema = EmptyPartSchema.extend({ - data: z.unknown(), -}); - -/** - * Data part. - */ -export type DataPart = z.infer; - -/** - * Zod schema of a custom part. - */ -export const CustomPartSchema = EmptyPartSchema.extend({ - custom: z.record(z.any()), -}); - -/** - * Custom part. - */ -export type CustomPart = z.infer; - -/** - * Zod schema of a resource part. - */ -export const ResourcePartSchema = EmptyPartSchema.extend({ - resource: z.object({ - uri: z.string(), - }), -}); - -/** - * Resource part. - */ -export type ResourcePart = z.infer; - -export const PartSchema = z.union([TextPartSchema, MediaPartSchema]); -export type Part = z.infer; +import type { Embedding } from './embedder.js'; +import { PartSchema, type Part } from './parts.js'; // We need both metadata and embedMetadata because they can // contain the same fields (e.g. video start/stop) with different values. diff --git a/js/ai/src/index.ts b/js/ai/src/index.ts index 3f80d093d4..7baccf7ee6 100644 --- a/js/ai/src/index.ts +++ b/js/ai/src/index.ts @@ -15,13 +15,7 @@ */ export { checkOperation } from './check-operation.js'; -export { - Document, - DocumentDataSchema, - type DocumentData, - type ToolRequest, - type ToolResponse, -} from './document.js'; +export { Document, DocumentDataSchema, type DocumentData } from './document.js'; export { embed, embedderActionMetadata, @@ -88,6 +82,7 @@ export { type ToolRequestPart, type ToolResponsePart, } from './model.js'; +export { type ToolRequest, type ToolResponse } from './parts.js'; export { defineHelper, definePartial, diff --git a/js/ai/src/model-types.ts b/js/ai/src/model-types.ts index e64381345f..be2a18fb7c 100644 --- a/js/ai/src/model-types.ts +++ b/js/ai/src/model-types.ts @@ -15,17 +15,17 @@ */ import { OperationSchema, z } from '@genkit-ai/core'; +import { DocumentDataSchema } from './document.js'; import { CustomPartSchema, DataPartSchema, - DocumentDataSchema, MediaPartSchema, ReasoningPartSchema, ResourcePartSchema, TextPartSchema, ToolRequestPartSchema, ToolResponsePartSchema, -} from './document.js'; +} from './parts.js'; // // IMPORTANT: Please keep type definitions in sync with diff --git a/js/ai/src/model.ts b/js/ai/src/model.ts index 883397e301..7877133ba3 100644 --- a/js/ai/src/model.ts +++ b/js/ai/src/model.ts @@ -35,20 +35,6 @@ import { logger } from '@genkit-ai/core/logging'; import type { Registry } from '@genkit-ai/core/registry'; import { toJsonSchema } from '@genkit-ai/core/schema'; import { performance } from 'node:perf_hooks'; -import { - CustomPartSchema, - DataPartSchema, - MediaPartSchema, - TextPartSchema, - ToolRequestPartSchema, - ToolResponsePartSchema, - type CustomPart, - type DataPart, - type MediaPart, - type TextPart, - type ToolRequestPart, - type ToolResponsePart, -} from './document.js'; import { CandidateData, GenerateRequest, @@ -66,6 +52,20 @@ import { augmentWithContext, simulateConstrainedGeneration, } from './model/middleware.js'; +import { + CustomPartSchema, + DataPartSchema, + MediaPartSchema, + TextPartSchema, + ToolRequestPartSchema, + ToolResponsePartSchema, + type CustomPart, + type DataPart, + type MediaPart, + type TextPart, + type ToolRequestPart, + type ToolResponsePart, +} from './parts.js'; export { defineGenerateAction } from './generate/action.js'; export * from './model-types.js'; export { diff --git a/js/ai/src/parts.ts b/js/ai/src/parts.ts new file mode 100644 index 0000000000..32117891da --- /dev/null +++ b/js/ai/src/parts.ts @@ -0,0 +1,179 @@ +/** + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { z } from '@genkit-ai/core'; + +const EmptyPartSchema = z.object({ + text: z.never().optional(), + media: z.never().optional(), + toolRequest: z.never().optional(), + toolResponse: z.never().optional(), + data: z.unknown().optional(), + metadata: z.record(z.unknown()).optional(), + custom: z.record(z.unknown()).optional(), + reasoning: z.never().optional(), + resource: z.never().optional(), +}); + +/** + * Zod schema for a text part. + */ +export const TextPartSchema = EmptyPartSchema.extend({ + /** The text of the message. */ + text: z.string(), +}); + +/** + * Zod schema for a reasoning part. + */ +export const ReasoningPartSchema = EmptyPartSchema.extend({ + /** The reasoning text of the message. */ + reasoning: z.string(), +}); + +/** + * Text part. + */ +export type TextPart = z.infer; + +/** + * Zod schema of media. + */ +export const MediaSchema = z.object({ + /** The media content type. Inferred from data uri if not provided. */ + contentType: z.string().optional(), + /** A `data:` or `https:` uri containing the media content. */ + url: z.string(), +}); + +/** + * Zod schema of a media part. + */ +export const MediaPartSchema = EmptyPartSchema.extend({ + media: MediaSchema, +}); + +/** + * Media part. + */ +export type MediaPart = z.infer; + +/** + * Zod schema of a tool request. + */ +export const ToolRequestSchema = z.object({ + /** The call id or reference for a specific request. */ + ref: z.string().optional(), + /** The name of the tool to call. */ + name: z.string(), + /** The input parameters for the tool, usually a JSON object. */ + input: z.unknown().optional(), +}); +export type ToolRequest = z.infer; + +/** + * Zod schema of a tool request part. + */ +export const ToolRequestPartSchema = EmptyPartSchema.extend({ + /** A request for a tool to be executed, usually provided by a model. */ + toolRequest: ToolRequestSchema, +}); + +/** + * Tool part. + */ +export type ToolRequestPart = z.infer; + +/** + * Zod schema of a tool response. + */ +const ToolResponseSchemaBase = z.object({ + /** The call id or reference for a specific request. */ + ref: z.string().optional(), + /** The name of the tool. */ + name: z.string(), + /** The output data returned from the tool, usually a JSON object. */ + output: z.unknown().optional(), + payloadStrategy: z.enum(['both', 'fallback']).optional(), // default: both +}); + +/** + * Tool response part. + */ +export type ToolResponse = z.infer & { + content?: Part[]; +}; + +export const ToolResponseSchema: z.ZodType = + ToolResponseSchemaBase.extend({ + content: z.array(z.any()).optional(), + // TODO: switch to this once we have effective recursive schema support across the board. + // content: z.array(z.lazy(() => PartSchema)).optional(), + }); + +/** + * Zod schema of a tool response part. + */ +export const ToolResponsePartSchema = EmptyPartSchema.extend({ + /** A provided response to a tool call. */ + toolResponse: ToolResponseSchema, +}); + +/** + * Tool response part. + */ +export type ToolResponsePart = z.infer; + +/** + * Zod schema of a data part. + */ +export const DataPartSchema = EmptyPartSchema.extend({ + data: z.unknown(), +}); + +/** + * Data part. + */ +export type DataPart = z.infer; + +/** + * Zod schema of a custom part. + */ +export const CustomPartSchema = EmptyPartSchema.extend({ + custom: z.record(z.any()), +}); + +/** + * Custom part. + */ +export type CustomPart = z.infer; + +/** + * Zod schema of a resource part. + */ +export const ResourcePartSchema = EmptyPartSchema.extend({ + resource: z.object({ + uri: z.string(), + }), +}); + +/** + * Resource part. + */ +export type ResourcePart = z.infer; + +export const PartSchema = z.union([TextPartSchema, MediaPartSchema]); +export type Part = z.infer; diff --git a/js/ai/src/reranker.ts b/js/ai/src/reranker.ts index 45cf7deba5..402777c71f 100644 --- a/js/ai/src/reranker.ts +++ b/js/ai/src/reranker.ts @@ -17,7 +17,7 @@ import { action, z, type Action } from '@genkit-ai/core'; import type { Registry } from '@genkit-ai/core/registry'; import { toJsonSchema } from '@genkit-ai/core/schema'; -import { PartSchema, type Part } from './document.js'; +import { PartSchema, type Part } from './parts.js'; import { Document, DocumentDataSchema, diff --git a/js/ai/src/retriever.ts b/js/ai/src/retriever.ts index 40bdf7e535..01702acb4c 100644 --- a/js/ai/src/retriever.ts +++ b/js/ai/src/retriever.ts @@ -20,14 +20,8 @@ import { toJsonSchema } from '@genkit-ai/core/schema'; import { Document, DocumentDataSchema, type DocumentData } from './document.js'; import type { EmbedderInfo } from './embedder.js'; -export { - Document, - DocumentDataSchema, - type DocumentData, - type MediaPart, - type Part, - type TextPart, -} from './document.js'; +export { Document, DocumentDataSchema, type DocumentData } from './document.js'; +export { type MediaPart, type Part, type TextPart } from './parts.js'; /** * Retriever implementation function signature. diff --git a/py/packages/genkit/src/genkit/core/typing.py b/py/packages/genkit/src/genkit/core/typing.py index 0673136c52..c70cd142c4 100644 --- a/py/packages/genkit/src/genkit/core/typing.py +++ b/py/packages/genkit/src/genkit/core/typing.py @@ -44,54 +44,6 @@ class Model(RootModel[Any]): root: Any -class CustomPart(BaseModel): - """Model for custompart data.""" - - model_config = ConfigDict(extra='forbid', populate_by_name=True) - text: Any | None = None - media: Any | None = None - tool_request: Any | None = Field(None, alias='toolRequest') - tool_response: Any | None = Field(None, alias='toolResponse') - data: Any | None = None - metadata: dict[str, Any] | None = None - custom: dict[str, Any] - reasoning: Any | None = None - resource: Any | None = None - - -class Media(BaseModel): - """Model for media data.""" - - model_config = ConfigDict(extra='forbid', populate_by_name=True) - content_type: str | None = Field(None, alias='contentType') - url: str - - -class Resource1(BaseModel): - """Model for resource1 data.""" - - model_config = ConfigDict(extra='forbid', populate_by_name=True) - uri: str - - -class ToolRequest(BaseModel): - """Model for toolrequest data.""" - - model_config = ConfigDict(extra='forbid', populate_by_name=True) - ref: str | None = None - name: str - input: Any | None = None - - -class ToolResponse(BaseModel): - """Model for toolresponse data.""" - - model_config = ConfigDict(extra='forbid', populate_by_name=True) - ref: str | None = None - name: str - output: Any | None = None - - class Embedding(BaseModel): """Model for embedding data.""" @@ -155,8 +107,8 @@ class GenkitErrorDetails(BaseModel): trace_id: str = Field(..., alias='traceId') -class Data1(BaseModel): - """Model for data1 data.""" +class Data(BaseModel): + """Model for data data.""" model_config = ConfigDict(extra='forbid', populate_by_name=True) genkit_error_message: str | None = Field(None, alias='genkitErrorMessage') @@ -170,7 +122,7 @@ class GenkitError(BaseModel): message: str stack: str | None = None details: Any | None = None - data: Data1 | None = None + data: Data | None = None class Code(StrEnum): @@ -190,6 +142,21 @@ class CandidateError(BaseModel): message: str | None = None +class CustomPart(BaseModel): + """Model for custompart data.""" + + model_config = ConfigDict(extra='forbid', populate_by_name=True) + text: Any | None = None + media: Any | None = None + tool_request: Any | None = Field(None, alias='toolRequest') + tool_response: Any | None = Field(None, alias='toolResponse') + data: Any | None = None + metadata: dict[str, Any] | None = None + custom: dict[str, Any] + reasoning: Any | None = None + resource: Any | None = None + + class FinishReason(StrEnum): """Enumeration of finishreason values.""" @@ -325,6 +292,13 @@ class OutputConfig(BaseModel): content_type: str | None = Field(None, alias='contentType') +class Resource1(BaseModel): + """Model for resource1 data.""" + + model_config = ConfigDict(extra='forbid', populate_by_name=True) + uri: str + + class Role(StrEnum): """Enumeration of role values.""" @@ -349,6 +323,41 @@ class ToolDefinition(BaseModel): metadata: dict[str, Any] | None = Field(None, description='additional metadata for this tool definition') +class Media(BaseModel): + """Model for media data.""" + + model_config = ConfigDict(extra='forbid', populate_by_name=True) + content_type: str | None = Field(None, alias='contentType') + url: str + + +class ToolRequest(BaseModel): + """Model for toolrequest data.""" + + model_config = ConfigDict(extra='forbid', populate_by_name=True) + ref: str | None = None + name: str + input: Any | None = None + + +class PayloadStrategy(StrEnum): + """Enumeration of payloadstrategy values.""" + + BOTH = 'both' + FALLBACK = 'fallback' + + +class ToolResponse(BaseModel): + """Model for toolresponse data.""" + + model_config = ConfigDict(extra='forbid', populate_by_name=True) + ref: str | None = None + name: str + output: Any | None = None + payload_strategy: PayloadStrategy | None = Field(None, alias='payloadStrategy') + content: list | None = None + + class CommonRerankerOptions(BaseModel): """Model for commonrerankeroptions data.""" @@ -489,8 +498,8 @@ class TraceIds(RootModel[list[str]]): root: list[str] -class Data(RootModel[Any]): - """Root model for data.""" +class DataModel(RootModel[Any]): + """Root model for datamodel.""" root: Any @@ -603,6 +612,42 @@ class Index(RootModel[float]): root: float +class EmbedResponse(BaseModel): + """Model for embedresponse data.""" + + model_config = ConfigDict(extra='forbid', populate_by_name=True) + embeddings: list[Embedding] + + +class BaseEvalDataPoint(BaseModel): + """Model for baseevaldatapoint data.""" + + model_config = ConfigDict(extra='forbid', populate_by_name=True) + input: Input | None = None + output: Output | None = None + context: Context | None = None + reference: Reference | None = None + test_case_id: str = Field(..., alias='testCaseId') + trace_ids: TraceIds | None = Field(None, alias='traceIds') + + +class EvalFnResponse(BaseModel): + """Model for evalfnresponse data.""" + + model_config = ConfigDict(extra='forbid', populate_by_name=True) + sample_index: float | None = Field(None, alias='sampleIndex') + test_case_id: str = Field(..., alias='testCaseId') + trace_id: str | None = Field(None, alias='traceId') + span_id: str | None = Field(None, alias='spanId') + evaluation: Score | list[Score] + + +class EvalResponse(RootModel[list[EvalFnResponse]]): + """Root model for evalresponse.""" + + root: list[EvalFnResponse] + + class DataPart(BaseModel): """Model for datapart data.""" @@ -626,7 +671,7 @@ class MediaPart(BaseModel): media: Media tool_request: ToolRequestModel | None = Field(None, alias='toolRequest') tool_response: ToolResponseModel | None = Field(None, alias='toolResponse') - data: Data | None = None + data: DataModel | None = None metadata: Metadata | None = None custom: Custom | None = None reasoning: Reasoning | None = None @@ -641,7 +686,7 @@ class ReasoningPart(BaseModel): media: MediaModel | None = None tool_request: ToolRequestModel | None = Field(None, alias='toolRequest') tool_response: ToolResponseModel | None = Field(None, alias='toolResponse') - data: Data | None = None + data: DataModel | None = None metadata: Metadata | None = None custom: Custom | None = None reasoning: str @@ -656,7 +701,7 @@ class ResourcePart(BaseModel): media: MediaModel | None = None tool_request: ToolRequestModel | None = Field(None, alias='toolRequest') tool_response: ToolResponseModel | None = Field(None, alias='toolResponse') - data: Data | None = None + data: DataModel | None = None metadata: Metadata | None = None custom: Custom | None = None reasoning: Reasoning | None = None @@ -671,7 +716,7 @@ class TextPart(BaseModel): media: MediaModel | None = None tool_request: ToolRequestModel | None = Field(None, alias='toolRequest') tool_response: ToolResponseModel | None = Field(None, alias='toolResponse') - data: Data | None = None + data: DataModel | None = None metadata: Metadata | None = None custom: Custom | None = None reasoning: Reasoning | None = None @@ -686,7 +731,7 @@ class ToolRequestPart(BaseModel): media: MediaModel | None = None tool_request: ToolRequest = Field(..., alias='toolRequest') tool_response: ToolResponseModel | None = Field(None, alias='toolResponse') - data: Data | None = None + data: DataModel | None = None metadata: Metadata | None = None custom: Custom | None = None reasoning: Reasoning | None = None @@ -701,70 +746,13 @@ class ToolResponsePart(BaseModel): media: MediaModel | None = None tool_request: ToolRequestModel | None = Field(None, alias='toolRequest') tool_response: ToolResponse = Field(..., alias='toolResponse') - data: Data | None = None + data: DataModel | None = None metadata: Metadata | None = None custom: Custom | None = None reasoning: Reasoning | None = None resource: Resource | None = None -class EmbedResponse(BaseModel): - """Model for embedresponse data.""" - - model_config = ConfigDict(extra='forbid', populate_by_name=True) - embeddings: list[Embedding] - - -class BaseEvalDataPoint(BaseModel): - """Model for baseevaldatapoint data.""" - - model_config = ConfigDict(extra='forbid', populate_by_name=True) - input: Input | None = None - output: Output | None = None - context: Context | None = None - reference: Reference | None = None - test_case_id: str = Field(..., alias='testCaseId') - trace_ids: TraceIds | None = Field(None, alias='traceIds') - - -class EvalFnResponse(BaseModel): - """Model for evalfnresponse data.""" - - model_config = ConfigDict(extra='forbid', populate_by_name=True) - sample_index: float | None = Field(None, alias='sampleIndex') - test_case_id: str = Field(..., alias='testCaseId') - trace_id: str | None = Field(None, alias='traceId') - span_id: str | None = Field(None, alias='spanId') - evaluation: Score | list[Score] - - -class EvalResponse(RootModel[list[EvalFnResponse]]): - """Root model for evalresponse.""" - - root: list[EvalFnResponse] - - -class Resume(BaseModel): - """Model for resume data.""" - - model_config = ConfigDict(extra='forbid', populate_by_name=True) - respond: list[ToolResponsePart] | None = None - restart: list[ToolRequestPart] | None = None - metadata: dict[str, Any] | None = None - - -class Part( - RootModel[ - TextPart | MediaPart | ToolRequestPart | ToolResponsePart | DataPart | CustomPart | ReasoningPart | ResourcePart - ] -): - """Root model for part.""" - - root: ( - TextPart | MediaPart | ToolRequestPart | ToolResponsePart | DataPart | CustomPart | ReasoningPart | ResourcePart - ) - - class Link(BaseModel): """Model for link data.""" @@ -814,16 +802,68 @@ class TraceData(BaseModel): spans: dict[str, SpanData] +class DocumentPart(RootModel[TextPart | MediaPart]): + """Root model for documentpart.""" + + root: TextPart | MediaPart + + +class Resume(BaseModel): + """Model for resume data.""" + + model_config = ConfigDict(extra='forbid', populate_by_name=True) + respond: list[ToolResponsePart] | None = None + restart: list[ToolRequestPart] | None = None + metadata: dict[str, Any] | None = None + + +class Part( + RootModel[ + TextPart | MediaPart | ToolRequestPart | ToolResponsePart | DataPart | CustomPart | ReasoningPart | ResourcePart + ] +): + """Root model for part.""" + + root: ( + TextPart | MediaPart | ToolRequestPart | ToolResponsePart | DataPart | CustomPart | ReasoningPart | ResourcePart + ) + + +class RankedDocumentData(BaseModel): + """Model for rankeddocumentdata data.""" + + model_config = ConfigDict(extra='forbid', populate_by_name=True) + content: list[DocumentPart] + metadata: RankedDocumentMetadata + + +class RerankerResponse(BaseModel): + """Model for rerankerresponse data.""" + + model_config = ConfigDict(extra='forbid', populate_by_name=True) + documents: list[RankedDocumentData] + + class Content(RootModel[list[Part]]): """Root model for content.""" root: list[Part] -class DocumentPart(RootModel[TextPart | MediaPart]): - """Root model for documentpart.""" +class DocumentData(BaseModel): + """Model for documentdata data.""" - root: TextPart | MediaPart + model_config = ConfigDict(extra='forbid', populate_by_name=True) + content: list[DocumentPart] + metadata: dict[str, Any] | None = None + + +class EmbedRequest(BaseModel): + """Model for embedrequest data.""" + + model_config = ConfigDict(extra='forbid', populate_by_name=True) + input: list[DocumentData] + options: Any | None = None class GenerateResponseChunk(BaseModel): @@ -857,41 +897,40 @@ class ModelResponseChunk(BaseModel): aggregated: Aggregated | None = None -class RankedDocumentData(BaseModel): - """Model for rankeddocumentdata data.""" +class RerankerRequest(BaseModel): + """Model for rerankerrequest data.""" model_config = ConfigDict(extra='forbid', populate_by_name=True) - content: list[DocumentPart] - metadata: RankedDocumentMetadata + query: DocumentData + documents: list[DocumentData] + options: Any | None = None -class RerankerResponse(BaseModel): - """Model for rerankerresponse data.""" +class RetrieverRequest(BaseModel): + """Model for retrieverrequest data.""" model_config = ConfigDict(extra='forbid', populate_by_name=True) - documents: list[RankedDocumentData] + query: DocumentData + options: Any | None = None -class Messages(RootModel[list[Message]]): - """Root model for messages.""" +class RetrieverResponse(BaseModel): + """Model for retrieverresponse data.""" - root: list[Message] + model_config = ConfigDict(extra='forbid', populate_by_name=True) + documents: list[DocumentData] -class DocumentData(BaseModel): - """Model for documentdata data.""" +class Docs(RootModel[list[DocumentData]]): + """Root model for docs.""" - model_config = ConfigDict(extra='forbid', populate_by_name=True) - content: list[DocumentPart] - metadata: dict[str, Any] | None = None + root: list[DocumentData] -class EmbedRequest(BaseModel): - """Model for embedrequest data.""" +class Messages(RootModel[list[Message]]): + """Root model for messages.""" - model_config = ConfigDict(extra='forbid', populate_by_name=True) - input: list[DocumentData] - options: Any | None = None + root: list[Message] class Candidate(BaseModel): @@ -952,42 +991,6 @@ class GenerateResponse(BaseModel): candidates: list[Candidate] | None = None -class RerankerRequest(BaseModel): - """Model for rerankerrequest data.""" - - model_config = ConfigDict(extra='forbid', populate_by_name=True) - query: DocumentData - documents: list[DocumentData] - options: Any | None = None - - -class RetrieverRequest(BaseModel): - """Model for retrieverrequest data.""" - - model_config = ConfigDict(extra='forbid', populate_by_name=True) - query: DocumentData - options: Any | None = None - - -class RetrieverResponse(BaseModel): - """Model for retrieverresponse data.""" - - model_config = ConfigDict(extra='forbid', populate_by_name=True) - documents: list[DocumentData] - - -class Docs(RootModel[list[DocumentData]]): - """Root model for docs.""" - - root: list[DocumentData] - - -class Request(RootModel[GenerateRequest]): - """Root model for request.""" - - root: GenerateRequest - - class ModelRequest(BaseModel): """Model for modelrequest data.""" @@ -1000,6 +1003,12 @@ class ModelRequest(BaseModel): docs: Docs | None = None +class Request(RootModel[GenerateRequest]): + """Root model for request.""" + + root: GenerateRequest + + class ModelResponse(BaseModel): """Model for modelresponse data.""" diff --git a/py/packages/genkit/tests/genkit/blocks/prompt_test.py b/py/packages/genkit/tests/genkit/blocks/prompt_test.py index 67b09291b5..1b62b92835 100644 --- a/py/packages/genkit/tests/genkit/blocks/prompt_test.py +++ b/py/packages/genkit/tests/genkit/blocks/prompt_test.py @@ -202,7 +202,8 @@ def test_tool(input: ToolInput): ), ] -@pytest.mark.skip(reason="issues when running on CI") + +@pytest.mark.skip(reason='issues when running on CI') @pytest.mark.asyncio @pytest.mark.parametrize( 'test_case, prompt, input, input_option, context, want_rendered',