| import { | ||
| extractErrorMessage | ||
| } from "./chunk-X6ZY2KFU.js"; | ||
| // src/output-validator/index.ts | ||
| import { Ajv } from "ajv"; | ||
| import { tool } from "ai"; | ||
| import { createHash } from "crypto"; | ||
| import { z } from "zod"; | ||
| // src/output-validator/prompt.ts | ||
| function getPrompt(config = {}) { | ||
| const schemaLine = config.schemaId ? `Configured schema id: ${config.schemaId}.` : "The schema is configured by the application when this tool is created."; | ||
| return `Validate the exact final JSON response content against the configured output schema. | ||
| ${schemaLine} | ||
| ## When to Use | ||
| - Before returning a final answer that must match a structured JSON output contract | ||
| - After drafting the complete final JSON response, with the exact response text as the content | ||
| - Again after fixing any validation errors returned by this tool | ||
| ## Usage Guidelines | ||
| - Call this tool before the final answer whenever structured output validation is required for the current turn. | ||
| - Pass the exact final JSON response text in the content parameter. | ||
| - If validation fails, revise the response to address every returned error and validate again. | ||
| - Only return the final answer after this tool reports valid: true. | ||
| - The configured schema may change between turns, so rely on the current tool instance and result schema id/hash.`; | ||
| } | ||
| // src/output-validator/index.ts | ||
| function createOutputValidator(config = {}) { | ||
| const schemaHash = getSchemaHash(config.schema); | ||
| const schemaId = config.schemaId ?? getSchemaLabel(config.schema); | ||
| const compiled = compileSchema(config); | ||
| return tool({ | ||
| description: config.description ?? getPrompt({ schemaId }), | ||
| inputSchema: z.object({ | ||
| content: z.string().describe("Exact final JSON response text to validate") | ||
| }), | ||
| execute: async ({ content }) => { | ||
| try { | ||
| if (config.schema === void 0) { | ||
| return "Error [output-validator]: No schema configured. Provide a schema via createOutputValidator({ schema })."; | ||
| } | ||
| if ("error" in compiled) { | ||
| return `Error [output-validator]: Invalid configured schema: ${compiled.error}`; | ||
| } | ||
| const parsed = parseJsonContent(content, schemaId, schemaHash); | ||
| if (!parsed.ok) { | ||
| return stringifyResult(parsed.result); | ||
| } | ||
| const valid = compiled.validate(parsed.value); | ||
| if (valid) { | ||
| return stringifyResult({ | ||
| valid: true, | ||
| schemaId, | ||
| schemaHash, | ||
| message: "Output matches the configured schema." | ||
| }); | ||
| } | ||
| return stringifyResult({ | ||
| valid: false, | ||
| schemaId, | ||
| schemaHash, | ||
| errors: formatAjvErrors(compiled.validate.errors) | ||
| }); | ||
| } catch (error) { | ||
| const msg = extractErrorMessage(error); | ||
| return `Error [output-validator]: ${msg}`; | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| var outputValidator = createOutputValidator(); | ||
| function compileSchema(config) { | ||
| if (config.schema === void 0) { | ||
| return { error: "No schema configured." }; | ||
| } | ||
| try { | ||
| const ajvOptions = config.ajvOptions; | ||
| const ajv = new Ajv({ | ||
| allErrors: true, | ||
| strict: false, | ||
| ...ajvOptions | ||
| }); | ||
| const validate = ajv.compile(config.schema); | ||
| if (validate.$async === true) { | ||
| return { error: "Async JSON Schemas are not supported." }; | ||
| } | ||
| return { validate }; | ||
| } catch (error) { | ||
| return { error: extractErrorMessage(error) }; | ||
| } | ||
| } | ||
| function parseJsonContent(content, schemaId, schemaHash) { | ||
| try { | ||
| return { ok: true, value: JSON.parse(content) }; | ||
| } catch (error) { | ||
| const msg = extractErrorMessage(error); | ||
| return { | ||
| ok: false, | ||
| result: { | ||
| valid: false, | ||
| schemaId, | ||
| schemaHash, | ||
| errors: [ | ||
| { | ||
| path: "/", | ||
| message: `Content is not valid JSON: ${msg}`, | ||
| keyword: "parse" | ||
| } | ||
| ] | ||
| } | ||
| }; | ||
| } | ||
| } | ||
| function formatAjvErrors(errors) { | ||
| return (errors ?? []).map((error) => ({ | ||
| path: getErrorPath(error), | ||
| message: error.message ?? `failed schema keyword "${error.keyword}"`, | ||
| keyword: error.keyword, | ||
| schemaPath: error.schemaPath, | ||
| params: error.params | ||
| })); | ||
| } | ||
| function getErrorPath(error) { | ||
| if (error.keyword === "required") { | ||
| const missing = getMissingProperty(error.params); | ||
| if (missing) { | ||
| return appendJsonPointer(error.instancePath, missing); | ||
| } | ||
| } | ||
| return error.instancePath || "/"; | ||
| } | ||
| function getMissingProperty(params) { | ||
| const missing = params.missingProperty; | ||
| return typeof missing === "string" && missing.length > 0 ? missing : void 0; | ||
| } | ||
| function appendJsonPointer(base, segment) { | ||
| const prefix = base && base !== "/" ? base : ""; | ||
| return `${prefix}/${escapeJsonPointerSegment(segment)}`; | ||
| } | ||
| function escapeJsonPointerSegment(segment) { | ||
| return segment.replace(/~/g, "~0").replace(/\//g, "~1"); | ||
| } | ||
| function getSchemaLabel(schema) { | ||
| if (!isRecord(schema)) { | ||
| return void 0; | ||
| } | ||
| for (const key of ["$id", "id", "title"]) { | ||
| const value = schema[key]; | ||
| if (typeof value === "string" && value.trim().length > 0) { | ||
| return value; | ||
| } | ||
| } | ||
| return void 0; | ||
| } | ||
| function getSchemaHash(schema) { | ||
| if (schema === void 0) { | ||
| return void 0; | ||
| } | ||
| try { | ||
| return createHash("sha256").update(JSON.stringify(schema)).digest("hex").slice(0, 12); | ||
| } catch { | ||
| return void 0; | ||
| } | ||
| } | ||
| function stringifyResult(result) { | ||
| return JSON.stringify(result, null, 2); | ||
| } | ||
| function isRecord(value) { | ||
| return typeof value === "object" && value !== null && !Array.isArray(value); | ||
| } | ||
| export { | ||
| getPrompt, | ||
| createOutputValidator, | ||
| outputValidator | ||
| }; |
| "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } | ||
| var _chunkKONXT2SFcjs = require('./chunk-KONXT2SF.cjs'); | ||
| // src/output-validator/index.ts | ||
| var _ajv = require('ajv'); | ||
| var _ai = require('ai'); | ||
| var _crypto = require('crypto'); | ||
| var _zod = require('zod'); | ||
| // src/output-validator/prompt.ts | ||
| function getPrompt(config = {}) { | ||
| const schemaLine = config.schemaId ? `Configured schema id: ${config.schemaId}.` : "The schema is configured by the application when this tool is created."; | ||
| return `Validate the exact final JSON response content against the configured output schema. | ||
| ${schemaLine} | ||
| ## When to Use | ||
| - Before returning a final answer that must match a structured JSON output contract | ||
| - After drafting the complete final JSON response, with the exact response text as the content | ||
| - Again after fixing any validation errors returned by this tool | ||
| ## Usage Guidelines | ||
| - Call this tool before the final answer whenever structured output validation is required for the current turn. | ||
| - Pass the exact final JSON response text in the content parameter. | ||
| - If validation fails, revise the response to address every returned error and validate again. | ||
| - Only return the final answer after this tool reports valid: true. | ||
| - The configured schema may change between turns, so rely on the current tool instance and result schema id/hash.`; | ||
| } | ||
| // src/output-validator/index.ts | ||
| function createOutputValidator(config = {}) { | ||
| const schemaHash = getSchemaHash(config.schema); | ||
| const schemaId = _nullishCoalesce(config.schemaId, () => ( getSchemaLabel(config.schema))); | ||
| const compiled = compileSchema(config); | ||
| return _ai.tool.call(void 0, { | ||
| description: _nullishCoalesce(config.description, () => ( getPrompt({ schemaId }))), | ||
| inputSchema: _zod.z.object({ | ||
| content: _zod.z.string().describe("Exact final JSON response text to validate") | ||
| }), | ||
| execute: async ({ content }) => { | ||
| try { | ||
| if (config.schema === void 0) { | ||
| return "Error [output-validator]: No schema configured. Provide a schema via createOutputValidator({ schema })."; | ||
| } | ||
| if ("error" in compiled) { | ||
| return `Error [output-validator]: Invalid configured schema: ${compiled.error}`; | ||
| } | ||
| const parsed = parseJsonContent(content, schemaId, schemaHash); | ||
| if (!parsed.ok) { | ||
| return stringifyResult(parsed.result); | ||
| } | ||
| const valid = compiled.validate(parsed.value); | ||
| if (valid) { | ||
| return stringifyResult({ | ||
| valid: true, | ||
| schemaId, | ||
| schemaHash, | ||
| message: "Output matches the configured schema." | ||
| }); | ||
| } | ||
| return stringifyResult({ | ||
| valid: false, | ||
| schemaId, | ||
| schemaHash, | ||
| errors: formatAjvErrors(compiled.validate.errors) | ||
| }); | ||
| } catch (error) { | ||
| const msg = _chunkKONXT2SFcjs.extractErrorMessage.call(void 0, error); | ||
| return `Error [output-validator]: ${msg}`; | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| var outputValidator = createOutputValidator(); | ||
| function compileSchema(config) { | ||
| if (config.schema === void 0) { | ||
| return { error: "No schema configured." }; | ||
| } | ||
| try { | ||
| const ajvOptions = config.ajvOptions; | ||
| const ajv = new (0, _ajv.Ajv)({ | ||
| allErrors: true, | ||
| strict: false, | ||
| ...ajvOptions | ||
| }); | ||
| const validate = ajv.compile(config.schema); | ||
| if (validate.$async === true) { | ||
| return { error: "Async JSON Schemas are not supported." }; | ||
| } | ||
| return { validate }; | ||
| } catch (error) { | ||
| return { error: _chunkKONXT2SFcjs.extractErrorMessage.call(void 0, error) }; | ||
| } | ||
| } | ||
| function parseJsonContent(content, schemaId, schemaHash) { | ||
| try { | ||
| return { ok: true, value: JSON.parse(content) }; | ||
| } catch (error) { | ||
| const msg = _chunkKONXT2SFcjs.extractErrorMessage.call(void 0, error); | ||
| return { | ||
| ok: false, | ||
| result: { | ||
| valid: false, | ||
| schemaId, | ||
| schemaHash, | ||
| errors: [ | ||
| { | ||
| path: "/", | ||
| message: `Content is not valid JSON: ${msg}`, | ||
| keyword: "parse" | ||
| } | ||
| ] | ||
| } | ||
| }; | ||
| } | ||
| } | ||
| function formatAjvErrors(errors) { | ||
| return (_nullishCoalesce(errors, () => ( []))).map((error) => ({ | ||
| path: getErrorPath(error), | ||
| message: _nullishCoalesce(error.message, () => ( `failed schema keyword "${error.keyword}"`)), | ||
| keyword: error.keyword, | ||
| schemaPath: error.schemaPath, | ||
| params: error.params | ||
| })); | ||
| } | ||
| function getErrorPath(error) { | ||
| if (error.keyword === "required") { | ||
| const missing = getMissingProperty(error.params); | ||
| if (missing) { | ||
| return appendJsonPointer(error.instancePath, missing); | ||
| } | ||
| } | ||
| return error.instancePath || "/"; | ||
| } | ||
| function getMissingProperty(params) { | ||
| const missing = params.missingProperty; | ||
| return typeof missing === "string" && missing.length > 0 ? missing : void 0; | ||
| } | ||
| function appendJsonPointer(base, segment) { | ||
| const prefix = base && base !== "/" ? base : ""; | ||
| return `${prefix}/${escapeJsonPointerSegment(segment)}`; | ||
| } | ||
| function escapeJsonPointerSegment(segment) { | ||
| return segment.replace(/~/g, "~0").replace(/\//g, "~1"); | ||
| } | ||
| function getSchemaLabel(schema) { | ||
| if (!isRecord(schema)) { | ||
| return void 0; | ||
| } | ||
| for (const key of ["$id", "id", "title"]) { | ||
| const value = schema[key]; | ||
| if (typeof value === "string" && value.trim().length > 0) { | ||
| return value; | ||
| } | ||
| } | ||
| return void 0; | ||
| } | ||
| function getSchemaHash(schema) { | ||
| if (schema === void 0) { | ||
| return void 0; | ||
| } | ||
| try { | ||
| return _crypto.createHash.call(void 0, "sha256").update(JSON.stringify(schema)).digest("hex").slice(0, 12); | ||
| } catch (e) { | ||
| return void 0; | ||
| } | ||
| } | ||
| function stringifyResult(result) { | ||
| return JSON.stringify(result, null, 2); | ||
| } | ||
| function isRecord(value) { | ||
| return typeof value === "object" && value !== null && !Array.isArray(value); | ||
| } | ||
| exports.getPrompt = getPrompt; exports.createOutputValidator = createOutputValidator; exports.outputValidator = outputValidator; |
| "use strict";Object.defineProperty(exports, "__esModule", {value: true}); | ||
| var _chunkYRUGHL6Scjs = require('../chunk-YRUGHL6S.cjs'); | ||
| require('../chunk-KONXT2SF.cjs'); | ||
| exports.createOutputValidator = _chunkYRUGHL6Scjs.createOutputValidator; exports.outputValidator = _chunkYRUGHL6Scjs.outputValidator; exports.outputValidatorPrompt = _chunkYRUGHL6Scjs.getPrompt; |
| import * as ai from 'ai'; | ||
| /** | ||
| * Generate the description prompt for the output-validator tool. | ||
| * | ||
| * @param config - The same config passed to {@link createOutputValidator}. | ||
| * @returns The full description string for the output-validator tool. | ||
| */ | ||
| declare function getPrompt(config?: Pick<OutputValidatorConfig, 'schemaId'>): string; | ||
| type JsonSchemaValue = string | number | boolean | null | JsonSchemaObject | JsonSchemaValue[]; | ||
| interface JsonSchemaObject { | ||
| [key: string]: JsonSchemaValue | undefined; | ||
| } | ||
| type JsonSchema = boolean | JsonSchemaObject; | ||
| interface OutputValidatorConfig { | ||
| /** | ||
| * JSON Schema used to validate the final output content. | ||
| * Bind a fresh schema per turn when the expected output shape changes. | ||
| */ | ||
| schema?: JsonSchema; | ||
| /** Stable identifier included in validation results for debugging. */ | ||
| schemaId?: string; | ||
| /** Ajv options used by the validator. */ | ||
| ajvOptions?: Record<string, unknown>; | ||
| /** Override the default tool description. */ | ||
| description?: string; | ||
| } | ||
| interface OutputValidationError { | ||
| path: string; | ||
| message: string; | ||
| keyword: string; | ||
| schemaPath?: string; | ||
| params?: Record<string, unknown>; | ||
| } | ||
| interface OutputValidationResult { | ||
| valid: boolean; | ||
| schemaId?: string; | ||
| schemaHash?: string; | ||
| message?: string; | ||
| errors?: OutputValidationError[]; | ||
| } | ||
| /** | ||
| * Creates an output validator tool with a JSON Schema bound at creation time. | ||
| * | ||
| * The model only supplies the drafted final JSON response content. The schema | ||
| * stays under application control, which prevents an old or model-supplied | ||
| * schema from changing the validation contract during a turn. | ||
| * | ||
| * @param config - Validator configuration with the current turn's schema. | ||
| * @returns A Vercel AI SDK tool that validates final JSON output content. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * import { createOutputValidator } from 'agentool/output-validator'; | ||
| * | ||
| * const outputValidator = createOutputValidator({ | ||
| * schemaId: 'answer-v1', | ||
| * schema: { | ||
| * type: 'object', | ||
| * additionalProperties: false, | ||
| * required: ['answer'], | ||
| * properties: { answer: { type: 'string' } }, | ||
| * }, | ||
| * }); | ||
| * ``` | ||
| */ | ||
| declare function createOutputValidator(config?: OutputValidatorConfig): ai.Tool<{ | ||
| content: string; | ||
| }, string>; | ||
| /** | ||
| * Default validator instance. Configure a schema with createOutputValidator() | ||
| * for normal use. | ||
| */ | ||
| declare const outputValidator: ai.Tool<{ | ||
| content: string; | ||
| }, string>; | ||
| export { type JsonSchema, type JsonSchemaObject, type JsonSchemaValue, type OutputValidationError, type OutputValidationResult, type OutputValidatorConfig, createOutputValidator, outputValidator, getPrompt as outputValidatorPrompt }; |
| import * as ai from 'ai'; | ||
| /** | ||
| * Generate the description prompt for the output-validator tool. | ||
| * | ||
| * @param config - The same config passed to {@link createOutputValidator}. | ||
| * @returns The full description string for the output-validator tool. | ||
| */ | ||
| declare function getPrompt(config?: Pick<OutputValidatorConfig, 'schemaId'>): string; | ||
| type JsonSchemaValue = string | number | boolean | null | JsonSchemaObject | JsonSchemaValue[]; | ||
| interface JsonSchemaObject { | ||
| [key: string]: JsonSchemaValue | undefined; | ||
| } | ||
| type JsonSchema = boolean | JsonSchemaObject; | ||
| interface OutputValidatorConfig { | ||
| /** | ||
| * JSON Schema used to validate the final output content. | ||
| * Bind a fresh schema per turn when the expected output shape changes. | ||
| */ | ||
| schema?: JsonSchema; | ||
| /** Stable identifier included in validation results for debugging. */ | ||
| schemaId?: string; | ||
| /** Ajv options used by the validator. */ | ||
| ajvOptions?: Record<string, unknown>; | ||
| /** Override the default tool description. */ | ||
| description?: string; | ||
| } | ||
| interface OutputValidationError { | ||
| path: string; | ||
| message: string; | ||
| keyword: string; | ||
| schemaPath?: string; | ||
| params?: Record<string, unknown>; | ||
| } | ||
| interface OutputValidationResult { | ||
| valid: boolean; | ||
| schemaId?: string; | ||
| schemaHash?: string; | ||
| message?: string; | ||
| errors?: OutputValidationError[]; | ||
| } | ||
| /** | ||
| * Creates an output validator tool with a JSON Schema bound at creation time. | ||
| * | ||
| * The model only supplies the drafted final JSON response content. The schema | ||
| * stays under application control, which prevents an old or model-supplied | ||
| * schema from changing the validation contract during a turn. | ||
| * | ||
| * @param config - Validator configuration with the current turn's schema. | ||
| * @returns A Vercel AI SDK tool that validates final JSON output content. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * import { createOutputValidator } from 'agentool/output-validator'; | ||
| * | ||
| * const outputValidator = createOutputValidator({ | ||
| * schemaId: 'answer-v1', | ||
| * schema: { | ||
| * type: 'object', | ||
| * additionalProperties: false, | ||
| * required: ['answer'], | ||
| * properties: { answer: { type: 'string' } }, | ||
| * }, | ||
| * }); | ||
| * ``` | ||
| */ | ||
| declare function createOutputValidator(config?: OutputValidatorConfig): ai.Tool<{ | ||
| content: string; | ||
| }, string>; | ||
| /** | ||
| * Default validator instance. Configure a schema with createOutputValidator() | ||
| * for normal use. | ||
| */ | ||
| declare const outputValidator: ai.Tool<{ | ||
| content: string; | ||
| }, string>; | ||
| export { type JsonSchema, type JsonSchemaObject, type JsonSchemaValue, type OutputValidationError, type OutputValidationResult, type OutputValidatorConfig, createOutputValidator, outputValidator, getPrompt as outputValidatorPrompt }; |
| import { | ||
| createOutputValidator, | ||
| getPrompt, | ||
| outputValidator | ||
| } from "../chunk-3274NKQV.js"; | ||
| import "../chunk-X6ZY2KFU.js"; | ||
| export { | ||
| createOutputValidator, | ||
| outputValidator, | ||
| getPrompt as outputValidatorPrompt | ||
| }; |
+9
-1
@@ -18,2 +18,7 @@ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); | ||
| var _chunkYRUGHL6Scjs = require('./chunk-YRUGHL6S.cjs'); | ||
| var _chunkB76NYX22cjs = require('./chunk-B76NYX22.cjs'); | ||
@@ -173,2 +178,5 @@ | ||
| exports.askUser = _chunkKUFZFNPTcjs.askUser; exports.askUserPrompt = _chunkKUFZFNPTcjs.getPrompt; exports.bash = _chunkCXBWF5ONcjs.bash; exports.bashPrompt = _chunkCXBWF5ONcjs.getPrompt; exports.compactMessages = _chunkB76NYX22cjs.compactMessages; exports.createAskUser = _chunkKUFZFNPTcjs.createAskUser; exports.createBash = _chunkCXBWF5ONcjs.createBash; exports.createDiff = _chunkOYLTQJXTcjs.createDiff; exports.createEdit = _chunk6ULQG2W2cjs.createEdit; exports.createGlob = _chunkYCWJVQYOcjs.createGlob; exports.createGrep = _chunkRIGL3JTScjs.createGrep; exports.createHttpRequest = _chunk5T3SQYI4cjs.createHttpRequest; exports.createLsp = _chunkNQIV6LBHcjs.createLsp; exports.createMemory = _chunkLNAR3NJQcjs.createMemory; exports.createMultiEdit = _chunkVPV6WG5Vcjs.createMultiEdit; exports.createRead = _chunkHG5T47NAcjs.createRead; exports.createSleep = _chunkJYTOARJVcjs.createSleep; exports.createTaskCreate = _chunkSFDZRLSXcjs.createTaskCreate; exports.createTaskGet = _chunkXGDE7S2Dcjs.createTaskGet; exports.createTaskList = _chunk3FT4ZPB2cjs.createTaskList; exports.createTaskUpdate = _chunkT6STO7PScjs.createTaskUpdate; exports.createToolSearch = _chunk2JBLVFB7cjs.createToolSearch; exports.createWebFetch = _chunkG6ZVJA4Vcjs.createWebFetch; exports.createWebSearch = _chunkCM3VRCNXcjs.createWebSearch; exports.createWrite = _chunkABXTBB2Ncjs.createWrite; exports.diff = _chunkOYLTQJXTcjs.diff; exports.diffPrompt = _chunkOYLTQJXTcjs.getPrompt; exports.edit = _chunk6ULQG2W2cjs.edit; exports.editPrompt = _chunk6ULQG2W2cjs.getPrompt; exports.glob = _chunkYCWJVQYOcjs.glob; exports.globPrompt = _chunkYCWJVQYOcjs.getPrompt; exports.grep = _chunkRIGL3JTScjs.grep; exports.grepPrompt = _chunkRIGL3JTScjs.getPrompt; exports.httpRequest = _chunk5T3SQYI4cjs.httpRequest; exports.httpRequestPrompt = _chunk5T3SQYI4cjs.getPrompt; exports.lsp = _chunkNQIV6LBHcjs.lsp; exports.lspPrompt = _chunkNQIV6LBHcjs.getPrompt; exports.memory = _chunkLNAR3NJQcjs.memory; exports.memoryPrompt = _chunkLNAR3NJQcjs.getPrompt; exports.multiEdit = _chunkVPV6WG5Vcjs.multiEdit; exports.multiEditPrompt = _chunkVPV6WG5Vcjs.getPrompt; exports.read = _chunkHG5T47NAcjs.read; exports.readPrompt = _chunkHG5T47NAcjs.getPrompt; exports.sleep = _chunkJYTOARJVcjs.sleep; exports.sleepPrompt = _chunkJYTOARJVcjs.getPrompt; exports.taskCreate = _chunkSFDZRLSXcjs.taskCreate; exports.taskCreatePrompt = _chunkSFDZRLSXcjs.getPrompt; exports.taskGet = _chunkXGDE7S2Dcjs.taskGet; exports.taskGetPrompt = _chunkXGDE7S2Dcjs.getPrompt; exports.taskList = _chunk3FT4ZPB2cjs.taskList; exports.taskListPrompt = _chunk3FT4ZPB2cjs.getPrompt; exports.taskUpdate = _chunkT6STO7PScjs.taskUpdate; exports.taskUpdatePrompt = _chunkT6STO7PScjs.getPrompt; exports.toolSearch = _chunk2JBLVFB7cjs.toolSearch; exports.toolSearchPrompt = _chunk2JBLVFB7cjs.getPrompt; exports.webFetch = _chunkG6ZVJA4Vcjs.webFetch; exports.webFetchPrompt = _chunkG6ZVJA4Vcjs.getPrompt; exports.webSearch = _chunkCM3VRCNXcjs.webSearch; exports.webSearchPrompt = _chunkCM3VRCNXcjs.getPrompt; exports.write = _chunkABXTBB2Ncjs.write; exports.writePrompt = _chunkABXTBB2Ncjs.getPrompt; | ||
| exports.askUser = _chunkKUFZFNPTcjs.askUser; exports.askUserPrompt = _chunkKUFZFNPTcjs.getPrompt; exports.bash = _chunkCXBWF5ONcjs.bash; exports.bashPrompt = _chunkCXBWF5ONcjs.getPrompt; exports.compactMessages = _chunkB76NYX22cjs.compactMessages; exports.createAskUser = _chunkKUFZFNPTcjs.createAskUser; exports.createBash = _chunkCXBWF5ONcjs.createBash; exports.createDiff = _chunkOYLTQJXTcjs.createDiff; exports.createEdit = _chunk6ULQG2W2cjs.createEdit; exports.createGlob = _chunkYCWJVQYOcjs.createGlob; exports.createGrep = _chunkRIGL3JTScjs.createGrep; exports.createHttpRequest = _chunk5T3SQYI4cjs.createHttpRequest; exports.createLsp = _chunkNQIV6LBHcjs.createLsp; exports.createMemory = _chunkLNAR3NJQcjs.createMemory; exports.createMultiEdit = _chunkVPV6WG5Vcjs.createMultiEdit; exports.createOutputValidator = _chunkYRUGHL6Scjs.createOutputValidator; exports.createRead = _chunkHG5T47NAcjs.createRead; exports.createSleep = _chunkJYTOARJVcjs.createSleep; exports.createTaskCreate = _chunkSFDZRLSXcjs.createTaskCreate; exports.createTaskGet = _chunkXGDE7S2Dcjs.createTaskGet; exports.createTaskList = _chunk3FT4ZPB2cjs.createTaskList; exports.createTaskUpdate = _chunkT6STO7PScjs.createTaskUpdate; exports.createToolSearch = _chunk2JBLVFB7cjs.createToolSearch; exports.createWebFetch = _chunkG6ZVJA4Vcjs.createWebFetch; exports.createWebSearch = _chunkCM3VRCNXcjs.createWebSearch; exports.createWrite = _chunkABXTBB2Ncjs.createWrite; exports.diff = _chunkOYLTQJXTcjs.diff; exports.diffPrompt = _chunkOYLTQJXTcjs.getPrompt; exports.edit = _chunk6ULQG2W2cjs.edit; exports.editPrompt = _chunk6ULQG2W2cjs.getPrompt; exports.glob = _chunkYCWJVQYOcjs.glob; exports.globPrompt = _chunkYCWJVQYOcjs.getPrompt; exports.grep = _chunkRIGL3JTScjs.grep; exports.grepPrompt = _chunkRIGL3JTScjs.getPrompt; exports.httpRequest = _chunk5T3SQYI4cjs.httpRequest; exports.httpRequestPrompt = _chunk5T3SQYI4cjs.getPrompt; exports.lsp = _chunkNQIV6LBHcjs.lsp; exports.lspPrompt = _chunkNQIV6LBHcjs.getPrompt; exports.memory = _chunkLNAR3NJQcjs.memory; exports.memoryPrompt = _chunkLNAR3NJQcjs.getPrompt; exports.multiEdit = _chunkVPV6WG5Vcjs.multiEdit; exports.multiEditPrompt = _chunkVPV6WG5Vcjs.getPrompt; exports.outputValidator = _chunkYRUGHL6Scjs.outputValidator; exports.outputValidatorPrompt = _chunkYRUGHL6Scjs.getPrompt; exports.read = _chunkHG5T47NAcjs.read; exports.readPrompt = _chunkHG5T47NAcjs.getPrompt; exports.sleep = _chunkJYTOARJVcjs.sleep; exports.sleepPrompt = _chunkJYTOARJVcjs.getPrompt; exports.taskCreate = _chunkSFDZRLSXcjs.taskCreate; exports.taskCreatePrompt = _chunkSFDZRLSXcjs.getPrompt; exports.taskGet = _chunkXGDE7S2Dcjs.taskGet; exports.taskGetPrompt = _chunkXGDE7S2Dcjs.getPrompt; exports.taskList = _chunk3FT4ZPB2cjs.taskList; exports.taskListPrompt = _chunk3FT4ZPB2cjs.getPrompt; exports.taskUpdate = _chunkT6STO7PScjs.taskUpdate; exports.taskUpdatePrompt = _chunkT6STO7PScjs.getPrompt; exports.toolSearch = _chunk2JBLVFB7cjs.toolSearch; exports.toolSearchPrompt = _chunk2JBLVFB7cjs.getPrompt; exports.webFetch = _chunkG6ZVJA4Vcjs.webFetch; exports.webFetchPrompt = _chunkG6ZVJA4Vcjs.getPrompt; exports.webSearch = _chunkCM3VRCNXcjs.webSearch; exports.webSearchPrompt = _chunkCM3VRCNXcjs.getPrompt; exports.write = _chunkABXTBB2Ncjs.write; exports.writePrompt = _chunkABXTBB2Ncjs.getPrompt; |
+1
-0
@@ -19,2 +19,3 @@ export { BashConfig, bash, bashPrompt, createBash } from './bash/index.cjs'; | ||
| export { HttpRequestConfig, createHttpRequest, httpRequest, httpRequestPrompt } from './http-request/index.cjs'; | ||
| export { JsonSchema, JsonSchemaObject, JsonSchemaValue, OutputValidationError, OutputValidationResult, OutputValidatorConfig, createOutputValidator, outputValidator, outputValidatorPrompt } from './output-validator/index.cjs'; | ||
| export { CompactMessagesOptions, CompactSummarizer, compactMessages } from './context-compaction/index.cjs'; | ||
@@ -21,0 +22,0 @@ export { AskUserConfig, askUser, askUserPrompt, createAskUser } from './ask-user/index.cjs'; |
+1
-0
@@ -19,2 +19,3 @@ export { BashConfig, bash, bashPrompt, createBash } from './bash/index.js'; | ||
| export { HttpRequestConfig, createHttpRequest, httpRequest, httpRequestPrompt } from './http-request/index.js'; | ||
| export { JsonSchema, JsonSchemaObject, JsonSchemaValue, OutputValidationError, OutputValidationResult, OutputValidatorConfig, createOutputValidator, outputValidator, outputValidatorPrompt } from './output-validator/index.js'; | ||
| export { CompactMessagesOptions, CompactSummarizer, compactMessages } from './context-compaction/index.js'; | ||
@@ -21,0 +22,0 @@ export { AskUserConfig, askUser, askUserPrompt, createAskUser } from './ask-user/index.js'; |
+12
-4
@@ -17,2 +17,7 @@ import { | ||
| import { | ||
| createOutputValidator, | ||
| getPrompt as getPrompt19, | ||
| outputValidator | ||
| } from "./chunk-3274NKQV.js"; | ||
| import { | ||
| compactMessages | ||
@@ -23,7 +28,7 @@ } from "./chunk-6CI3UDOJ.js"; | ||
| createAskUser, | ||
| getPrompt as getPrompt19 | ||
| getPrompt as getPrompt20 | ||
| } from "./chunk-L7R4UZSK.js"; | ||
| import { | ||
| createSleep, | ||
| getPrompt as getPrompt20, | ||
| getPrompt as getPrompt21, | ||
| sleep | ||
@@ -114,3 +119,3 @@ } from "./chunk-M74OQYNK.js"; | ||
| askUser, | ||
| getPrompt19 as askUserPrompt, | ||
| getPrompt20 as askUserPrompt, | ||
| bash, | ||
@@ -129,2 +134,3 @@ getPrompt as bashPrompt, | ||
| createMultiEdit, | ||
| createOutputValidator, | ||
| createRead, | ||
@@ -156,6 +162,8 @@ createSleep, | ||
| getPrompt9 as multiEditPrompt, | ||
| outputValidator, | ||
| getPrompt19 as outputValidatorPrompt, | ||
| read, | ||
| getPrompt4 as readPrompt, | ||
| sleep, | ||
| getPrompt20 as sleepPrompt, | ||
| getPrompt21 as sleepPrompt, | ||
| taskCreate, | ||
@@ -162,0 +170,0 @@ getPrompt11 as taskCreatePrompt, |
+9
-3
| { | ||
| "name": "agentool", | ||
| "version": "1.3.0", | ||
| "version": "1.4.0", | ||
| "type": "module", | ||
| "description": "21 AI agent tools + context-compaction helper as standalone Vercel AI SDK modules", | ||
| "description": "22 AI agent tools + context-compaction helper as standalone Vercel AI SDK modules", | ||
| "author": "Z-M-Huang", | ||
@@ -132,2 +132,7 @@ "license": "Apache-2.0", | ||
| }, | ||
| "./output-validator": { | ||
| "types": "./dist/output-validator/index.d.ts", | ||
| "import": "./dist/output-validator/index.js", | ||
| "require": "./dist/output-validator/index.cjs" | ||
| }, | ||
| "./context-compaction": { | ||
@@ -169,2 +174,3 @@ "types": "./dist/context-compaction/index.d.ts", | ||
| "dependencies": { | ||
| "ajv": "^8.20.0", | ||
| "diff": "^7.0.0", | ||
@@ -181,3 +187,3 @@ "turndown": "^7.2.0" | ||
| "@vitest/coverage-v8": "^3.0.0", | ||
| "ai": "^6.0.0", | ||
| "ai": "~6.0.175", | ||
| "dotenv": "^17.4.0", | ||
@@ -184,0 +190,0 @@ "eslint": "^10.2.0", |
+50
-3
@@ -5,3 +5,3 @@ <div align="center"> | ||
| **21 AI agent tools + context-compaction helper for the [Vercel AI SDK](https://sdk.vercel.ai/).** | ||
| **22 AI agent tools + context-compaction helper for the [Vercel AI SDK](https://sdk.vercel.ai/).** | ||
@@ -31,3 +31,3 @@ <p> | ||
| - **21 production-ready tools** -- bash, grep, glob, read, edit, write, web-fetch, web-search, tool-search, memory, multi-edit, diff, task-create, task-get, task-update, task-list, lsp, http-request, ask-user, sleep | ||
| - **22 production-ready tools** -- bash, grep, glob, read, edit, write, web-fetch, web-search, tool-search, output-validator, memory, multi-edit, diff, task-create, task-get, task-update, task-list, lsp, http-request, ask-user, sleep | ||
| - **Context-compaction middleware** -- transparent prompt compaction via `wrapLanguageModel()`, preserves system messages and recent turns | ||
@@ -39,3 +39,3 @@ - **Vercel AI SDK compatible** -- works with `generateText()`, `streamText()`, and any AI SDK provider (OpenAI, Anthropic, Google, etc.) | ||
| - **Never throws** -- every `execute()` returns a descriptive error string instead of throwing | ||
| - **Tree-shakeable** -- 22 subpath exports, only import what you need | ||
| - **Tree-shakeable** -- 23 subpath exports, only import what you need | ||
@@ -388,2 +388,46 @@ ## Installation | ||
| ### output-validator | ||
| Validate the exact final JSON response against a JSON Schema configured by the application. | ||
| ```typescript | ||
| import { createOutputValidator } from 'agentool/output-validator'; | ||
| const outputValidator = createOutputValidator({ | ||
| schemaId: 'answer-v1', | ||
| schema: { | ||
| type: 'object', | ||
| additionalProperties: false, | ||
| required: ['answer', 'confidence'], | ||
| properties: { | ||
| answer: { type: 'string' }, | ||
| confidence: { type: 'number', minimum: 0, maximum: 1 }, | ||
| }, | ||
| }, | ||
| }); | ||
| const result = await outputValidator.execute( | ||
| { content: '{"answer":"Use the validator per turn.","confidence":0.92}' }, | ||
| { toolCallId: 'id', messages: [] }, | ||
| ); | ||
| // Returns JSON: { "valid": true, "schemaId": "answer-v1", ... } | ||
| ``` | ||
| Use a fresh validator instance for the current turn's schema: | ||
| ```typescript | ||
| const tools = { | ||
| output_validator: createOutputValidator({ | ||
| schemaId: 'current-turn-output', | ||
| schema: currentTurnSchema, | ||
| }), | ||
| }; | ||
| ``` | ||
| If the schema changes on the next turn, create a new validator and pass it under the same tool name. No new chat session is required as long as your app rebuilds the tool list for that model call. | ||
| **Parameters:** `content` (string, exact final JSON response text) | ||
| --- | ||
| ### http-request | ||
@@ -741,2 +785,3 @@ | ||
| | `tool-search` | `tools?: Record<string, { description }>` -- tool registry | | ||
| | `output-validator` | `schema?: JsonSchema`, `schemaId?: string`, `ajvOptions?: Record<string, unknown>` | | ||
| | `lsp` | `servers?: Record<string, LspServerConfig>` -- LSP servers by file extension | | ||
@@ -777,2 +822,3 @@ | `http-request` | `defaultHeaders?: Record<string, string>` -- headers merged into every request | | ||
| toolSearch, createToolSearch, | ||
| outputValidator, createOutputValidator, | ||
| httpRequest, createHttpRequest, | ||
@@ -813,2 +859,3 @@ memory, createMemory, | ||
| import { toolSearch } from 'agentool/tool-search'; | ||
| import { outputValidator } from 'agentool/output-validator'; | ||
| import { lsp } from 'agentool/lsp'; | ||
@@ -815,0 +862,0 @@ import { compactMessages } from 'agentool/context-compaction'; // helper function |
396200
5.38%153
4.08%7818
6.01%893
5.56%5
25%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added