UNPKG

eve

Version:

Filesystem-first framework for durable backend AI agents that run anywhere.

1 lines 2.83 kB
import{z}from"#compiled/zod/index.js";import{createLogger}from"#internal/logging.js";import{parseJsonValue}from"#shared/json.js";import{formatValidationError}from"#runtime/validation.js";import{withToolOutputSerializationError}from"#harness/tool-output-serialization.js";const log=createLogger(`harness.tool-model-output`),CONTENT_FILE_WARN_BYTES=3145728,UNSUPPORTED_FILE_DATA_TAGS=new Set([`url`,`reference`,`text`]),toolModelOutputPartSchema=z.discriminatedUnion(`type`,[z.object({type:z.literal(`text`),text:z.string()}),z.object({type:z.literal(`file`),data:z.object({type:z.literal(`data`),data:z.string()}),mediaType:z.string().min(1),filename:z.string().optional()})]),toolModelOutputSchema=z.discriminatedUnion(`type`,[z.object({type:z.literal(`text`),value:z.string()}),z.object({type:z.literal(`json`),value:z.unknown()}),z.object({type:z.literal(`content`),value:z.array(toolModelOutputPartSchema).min(1)})]);function normalizeToolJsonOutput(e){let t=e.output===void 0?null:e.output;return withToolOutputSerializationError(e,()=>(parseJsonValue(t),t))}function normalizeToolModelOutput(e){return withToolOutputSerializationError({boundary:`toModelOutput`,toolCallId:e.toolCallId,toolName:e.toolName},()=>{assertSupportedFilePartData(e.output);let t=toolModelOutputSchema.safeParse(e.output);if(!t.success)throw TypeError(formatValidationError(t.error));let n=t.data;if(n.type===`json`)return{type:`json`,value:normalizeToolJsonOutput({boundary:`toModelOutput`,output:n.value,toolCallId:e.toolCallId,toolName:e.toolName})};if(n.type===`content`)for(let t of n.value)t.type===`file`&&warnOversizedFilePayload(t,e.toolName);return n})}function assertSupportedFilePartData(e){if(typeof e!=`object`||!e)return;let t=e;if(t.type===`content`&&Array.isArray(t.value))for(let e of t.value){if(typeof e!=`object`||!e)continue;let t=e;if(t.type!==`file`)continue;let n=t.data,r=typeof n==`object`&&n?n.data:void 0;if(isBinaryPayload(n)||isBinaryPayload(r))throw TypeError(`Expected file content part data to be a base64 string, received raw bytes. Base64-encode binary payloads before returning them from toModelOutput.`);let i=typeof n==`object`&&n?n.type:void 0;if(typeof i==`string`&&UNSUPPORTED_FILE_DATA_TAGS.has(i))throw TypeError(`File content part data tag "${i}" is not supported yet; only { type: "data" } with a base64 string is accepted.`)}}function warnOversizedFilePayload(e,t){let n=Math.floor(e.data.data.length*3/4);n<=CONTENT_FILE_WARN_BYTES||log.warn(`content-part file payload exceeds the inline size guideline — it is persisted in history and re-sent on every subsequent model call`,{estimatedBytes:n,mediaType:e.mediaType,toolName:t,warnBytes:CONTENT_FILE_WARN_BYTES})}function isBinaryPayload(e){return e instanceof Uint8Array||e instanceof ArrayBuffer}export{normalizeToolJsonOutput,normalizeToolModelOutput};