better-mastra 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +21 -0
  2. package/dist/evals/cli.js +3 -7
  3. package/dist/evals/cli.js.map +1 -1
  4. package/dist/tools/defineTool.d.ts.map +1 -1
  5. package/dist/tools/defineTool.js +7 -1
  6. package/dist/tools/defineTool.js.map +1 -1
  7. package/dist/tools/manifest.d.ts +23 -7
  8. package/dist/tools/manifest.d.ts.map +1 -1
  9. package/dist/tools/manifest.js +66 -6
  10. package/dist/tools/manifest.js.map +1 -1
  11. package/dist/tools/toolInputSchema.d.ts.map +1 -1
  12. package/dist/tools/toolInputSchema.js +8 -2
  13. package/dist/tools/toolInputSchema.js.map +1 -1
  14. package/dist/turn/index.d.ts +3 -3
  15. package/dist/turn/index.d.ts.map +1 -1
  16. package/dist/turn/index.js +2 -2
  17. package/dist/turn/index.js.map +1 -1
  18. package/dist/turn/replySuggestions.d.ts +2 -0
  19. package/dist/turn/replySuggestions.d.ts.map +1 -1
  20. package/dist/turn/replySuggestions.js +1 -1
  21. package/dist/turn/replySuggestions.js.map +1 -1
  22. package/dist/turn/runChatTurn.d.ts +6 -7
  23. package/dist/turn/runChatTurn.d.ts.map +1 -1
  24. package/dist/turn/runChatTurn.js +18 -29
  25. package/dist/turn/runChatTurn.js.map +1 -1
  26. package/dist/turn/threads.d.ts +21 -2
  27. package/dist/turn/threads.d.ts.map +1 -1
  28. package/dist/turn/threads.js +45 -8
  29. package/dist/turn/threads.js.map +1 -1
  30. package/dist/usage/index.d.ts +1 -0
  31. package/dist/usage/index.d.ts.map +1 -1
  32. package/dist/usage/index.js +1 -0
  33. package/dist/usage/index.js.map +1 -1
  34. package/dist/usage/userRequests.d.ts +47 -0
  35. package/dist/usage/userRequests.d.ts.map +1 -0
  36. package/dist/usage/userRequests.js +51 -0
  37. package/dist/usage/userRequests.js.map +1 -0
  38. package/package.json +2 -2
  39. package/src/evals/cli.ts +3 -10
  40. package/src/tools/defineTool.ts +8 -1
  41. package/src/tools/manifest.ts +102 -13
  42. package/src/tools/toolInputSchema.ts +18 -4
  43. package/src/turn/index.ts +3 -2
  44. package/src/turn/replySuggestions.ts +3 -1
  45. package/src/turn/runChatTurn.ts +30 -34
  46. package/src/turn/threads.ts +79 -9
  47. package/src/usage/index.ts +7 -0
  48. package/src/usage/userRequests.ts +97 -0
package/README.md CHANGED
@@ -79,3 +79,24 @@ Redis ops for a ~1,500-chunk turn:
79
79
  | This, cross-replica reconnect | +1 PUBLISH, +1 XADD and EXPIRE per 50 ms batch, reader XREADs |
80
80
 
81
81
  Failure behaviour: a buffer over `maxBufferBytes` (2 MB) keeps streaming but new reconnects get 204. If the owner crashes, its locator expires and the cross-replica reader ends with an `error` chunk after `idleTimeoutMs`; the client reloads the thread from Mastra memory. If Redis is down, turns still run and same-replica reconnects work; cross-replica reconnects return 204. Finished turns stay resumable for `graceMs` (30 s).
82
+
83
+ ## Per-user request limits (`better-mastra/usage`)
84
+
85
+ `admitUserRequest` charges one request against every window of a user's operation at once, or refuses it with the seconds until the fullest window has room. The keys hold an HMAC of the user id, never the id itself. Pass any Redis client's `EVAL`:
86
+
87
+ ```ts
88
+ import { admitUserRequest } from 'better-mastra/usage'
89
+
90
+ const admission = await admitUserRequest({
91
+ runScript: (script, keys, args) => redis.send('EVAL', [script, String(keys.length), ...keys, ...args.map(String)]),
92
+ secret: process.env.AUTH_SECRET,
93
+ keyPrefix: 'app:ai-usage',
94
+ operation: 'receipt',
95
+ userId,
96
+ windows: [
97
+ { name: 'minute', seconds: 60, limit: 5 },
98
+ { name: 'day', seconds: 86_400, limit: 50 }
99
+ ]
100
+ })
101
+ // { kind: 'admitted' } | { kind: 'limited', retryAfterSeconds } | { kind: 'unavailable', error }
102
+ ```
package/dist/evals/cli.js CHANGED
@@ -150,6 +150,8 @@ function inspect(report, prefixes) {
150
150
  const cli = defineCli({
151
151
  name: 'better-mastra-evals',
152
152
  description: "Real turns through the app's production turn, scored by checks and a judge",
153
+ // `better-mastra-evals` alone, or with options first, runs `run`.
154
+ defaultCommand: 'run',
153
155
  commands: {
154
156
  run: defineCommand({
155
157
  description: 'Run a suite and save its report',
@@ -184,12 +186,6 @@ const cli = defineCli({
184
186
  })
185
187
  }
186
188
  });
187
- // `run` is the default command: no command, or options first, runs it.
188
- const argv = process.argv.slice(2);
189
- const [first] = argv;
190
- if (first === undefined ||
191
- (first.startsWith('-') && first !== '-h' && first !== '--help'))
192
- argv.unshift('run');
193
189
  // App pools (database, Redis) keep the event loop alive after the last run.
194
- process.exit(await cli.run(argv));
190
+ process.exit(await cli.run());
195
191
  //# sourceMappingURL=cli.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/evals/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n// better-mastra-evals: real turns through the app's production turn, scored\n// by hard checks and a judge, against the app's `evals.config.ts`.\n// `better-mastra-evals --help` lists the commands; `run` is the default.\n//\n// Several --model values run the suite on each and print a model comparison.\n// Run it with Bun (`bunx --bun better-mastra-evals`) or Node 22.18+ so the\n// TypeScript config loads.\n\nimport { mkdir, readFile, stat, writeFile } from 'node:fs/promises'\nimport { resolve } from 'node:path'\nimport { pathToFileURL } from 'node:url'\nimport { defineCli, defineCommand } from 'hanzio/cli'\nimport { z } from 'zod'\nimport type { EvalCase } from './case.js'\nimport { type EvalConfig, runEvalSuite, selectCases } from './config.js'\nimport {\n\tcompareReports,\n\ttype EvalReport,\n\tformatModelComparison,\n\tformatReport\n} from './report.js'\n\nconst runInput = z.object({\n\tconfig: z.string().default('evals.config.ts').describe('Eval config module'),\n\tsuite: z.string().default('smoke').describe('Suite to run'),\n\tcase: z.array(z.string()).describe('Only cases whose id starts with this'),\n\ttag: z.string().optional().describe('Only cases with this tag'),\n\trepeats: z.number().default(3).describe('Runs per case'),\n\tconcurrency: z.number().default(3).describe('Cases in flight'),\n\tmodel: z\n\t\t.array(z.string())\n\t\t.describe('Model to run on; several print a comparison'),\n\tjudge: z.boolean().default(true).describe('Score runs with the config judge'),\n\tcompare: z.string().optional().describe('Baseline report to compare with'),\n\toutput: z\n\t\t.string()\n\t\t.optional()\n\t\t.describe('Report file to write; several models add -<model>'),\n\tverbose: z.boolean().describe('Keep app console logs')\n})\n\ntype RunInput = z.output<typeof runInput>\n\nasync function loadConfig(path: string): Promise<EvalConfig> {\n\tconst file = resolve(path)\n\tconst module = await import(pathToFileURL(file).href)\n\tif (!module.default) throw new Error(`${file} has no default export`)\n\treturn module.default\n}\n\nasync function readReport(file: string): Promise<EvalReport> {\n\treturn JSON.parse(await readFile(file, 'utf8'))\n}\n\n/** `--output` for one model, with the model before the extension when several run. */\nfunction outputFile(output: string, modelId: string, models: number) {\n\tif (models === 1) return resolve(output)\n\tconst model = modelId.replaceAll('/', '_')\n\tconst dot = output.lastIndexOf('.')\n\treturn resolve(\n\t\tdot > output.lastIndexOf('/')\n\t\t\t? `${output.slice(0, dot)}-${model}${output.slice(dot)}`\n\t\t\t: `${output}-${model}`\n\t)\n}\n\nasync function save(config: EvalConfig, report: EvalReport, output?: string) {\n\tif (output) {\n\t\tawait writeFile(output, `${JSON.stringify(report, null, '\\t')}\\n`)\n\t\treturn output\n\t}\n\tconst dir = resolve(config.outputDir ?? '.evals')\n\tawait mkdir(dir, { recursive: true })\n\tconst ignore = resolve(dir, '.gitignore')\n\tif (!(await stat(ignore).catch(() => null))) await writeFile(ignore, '*\\n')\n\tconst file = resolve(\n\t\tdir,\n\t\t`${report.startedAt.replaceAll(':', '-')}-${report.suite}-${report.modelId.replaceAll('/', '_')}.json`\n\t)\n\tawait writeFile(file, `${JSON.stringify(report, null, '\\t')}\\n`)\n\treturn file\n}\n\n/** Apps log to the console; while cases run that buries the progress lines. */\nfunction silenceLogs(verbose: boolean) {\n\tif (verbose) return () => {}\n\tconst { log, info, debug } = console\n\tconsole.log = console.info = console.debug = () => {}\n\treturn () => Object.assign(console, { log, info, debug })\n}\n\nasync function run(values: RunInput) {\n\tconst config = await loadConfig(values.config)\n\ttry {\n\t\treturn await runWith(config, values)\n\t} finally {\n\t\tawait config.teardown?.()\n\t}\n}\n\nasync function runWith(config: EvalConfig, values: RunInput) {\n\tawait config.setup?.()\n\tconst all =\n\t\ttypeof config.cases === 'function' ? await config.cases() : config.cases\n\tconst prefixes = values.case\n\tconst cases: readonly EvalCase<unknown>[] = selectCases(all, {\n\t\tsuite: values.suite,\n\t\tprefixes,\n\t\t...(values.tag ? { tag: values.tag } : {})\n\t})\n\tconst models = values.model.length ? values.model : [config.defaultModel]\n\tconst reports: EvalReport[] = []\n\tfor (const modelId of models) {\n\t\tconsole.error(\n\t\t\t`Running ${cases.length} cases x${values.repeats} on ${modelId}${config.judge && values.judge ? ', judged' : ''}`\n\t\t)\n\t\tconst restore = silenceLogs(values.verbose)\n\t\tconst report = await runEvalSuite(config, {\n\t\t\tcases,\n\t\t\tsuite: prefixes.length ? 'selected' : values.suite,\n\t\t\tmodelId,\n\t\t\trepeats: values.repeats,\n\t\t\tconcurrency: values.concurrency,\n\t\t\tjudge: values.judge,\n\t\t\tonRun: (testCase, result) =>\n\t\t\t\tconsole.error(`${result.pass ? 'pass' : 'FAIL'} ${testCase.id}`)\n\t\t}).finally(restore)\n\t\tconsole.log(formatReport(report))\n\t\tconst output =\n\t\t\tvalues.output && outputFile(values.output, modelId, models.length)\n\t\tconsole.log(`\\n${await save(config, report, output)}\\n`)\n\t\treports.push(report)\n\t}\n\tif (reports.length > 1) console.log(formatModelComparison(reports))\n\tconst [first, ...rest] = reports\n\tfor (const report of rest) {\n\t\tif (first) console.log(`\\n${compareReports(first, report)}`)\n\t}\n\tif (values.compare && first) {\n\t\tconsole.log(`\\n${compareReports(await readReport(values.compare), first)}`)\n\t}\n\tconst failed = reports.some((report) =>\n\t\treport.results.some((result) => result.runs.some((r) => !r.pass))\n\t)\n\treturn failed ? 1 : 0\n}\n\nfunction inspect(report: EvalReport, prefixes: readonly string[]) {\n\tfor (const result of report.results) {\n\t\tif (\n\t\t\tprefixes.length &&\n\t\t\t!prefixes.some((prefix) => result.caseId.startsWith(prefix))\n\t\t)\n\t\t\tcontinue\n\t\tresult.runs.forEach((run, index) => {\n\t\t\tconsole.log(\n\t\t\t\t`\\n=== ${result.caseId} #${index + 1} ${run.pass ? 'pass' : 'FAIL'}`\n\t\t\t)\n\t\t\tfor (const check of run.checks.filter((check) => !check.pass)) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t` ✗ ${check.check}${check.detail ? ` (${check.detail})` : ''}`\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (run.verdict) console.log(` judge: ${JSON.stringify(run.verdict)}`)\n\t\t\tif (run.judgeError) console.log(` judge failed: ${run.judgeError}`)\n\t\t\tfor (const turn of run.trace.turns) {\n\t\t\t\tconsole.log(`\\n User: ${turn.userText}`)\n\t\t\t\tfor (const call of turn.toolCalls) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t` ${call.name} [${call.state}] ${JSON.stringify(call.input).slice(0, 200)}${call.errorText ? ` ERROR ${call.errorText}` : ''}`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tconsole.log(\n\t\t\t\t\t` Assistant (${turn.firstTextMs === null ? '-' : `${(turn.firstTextMs / 1000).toFixed(1)}s`}, ${turn.steps} steps): ${turn.replyText}`\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\t}\n}\n\nconst cli = defineCli({\n\tname: 'better-mastra-evals',\n\tdescription:\n\t\t\"Real turns through the app's production turn, scored by checks and a judge\",\n\tcommands: {\n\t\trun: defineCommand({\n\t\t\tdescription: 'Run a suite and save its report',\n\t\t\tinput: runInput,\n\t\t\trun: async (input, ctx) => {\n\t\t\t\tctx.exitCode = await run(input)\n\t\t\t}\n\t\t}),\n\t\tinspect: defineCommand({\n\t\t\tdescription: \"Print a report's failed checks and transcripts\",\n\t\t\tinput: z.object({\n\t\t\t\treport: z.string().meta({ positional: true }).describe('Report file'),\n\t\t\t\tcase: z\n\t\t\t\t\t.array(z.string())\n\t\t\t\t\t.describe('Only cases whose id starts with this')\n\t\t\t}),\n\t\t\trun: async (input) => inspect(await readReport(input.report), input.case)\n\t\t}),\n\t\tcompare: defineCommand({\n\t\t\tdescription: 'Compare a candidate report with a baseline',\n\t\t\tinput: z.object({\n\t\t\t\tbaseline: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.meta({ positional: true })\n\t\t\t\t\t.describe('Baseline report file'),\n\t\t\t\tcandidate: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.meta({ positional: true })\n\t\t\t\t\t.describe('Candidate report file')\n\t\t\t}),\n\t\t\trun: async (input) =>\n\t\t\t\tcompareReports(\n\t\t\t\t\tawait readReport(input.baseline),\n\t\t\t\t\tawait readReport(input.candidate)\n\t\t\t\t)\n\t\t})\n\t}\n})\n\n// `run` is the default command: no command, or options first, runs it.\nconst argv = process.argv.slice(2)\nconst [first] = argv\nif (\n\tfirst === undefined ||\n\t(first.startsWith('-') && first !== '-h' && first !== '--help')\n)\n\targv.unshift('run')\n\n// App pools (database, Redis) keep the event loop alive after the last run.\nprocess.exit(await cli.run(argv))\n"]}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/evals/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n// better-mastra-evals: real turns through the app's production turn, scored\n// by hard checks and a judge, against the app's `evals.config.ts`.\n// `better-mastra-evals --help` lists the commands; `run` is the default.\n//\n// Several --model values run the suite on each and print a model comparison.\n// Run it with Bun (`bunx --bun better-mastra-evals`) or Node 22.18+ so the\n// TypeScript config loads.\n\nimport { mkdir, readFile, stat, writeFile } from 'node:fs/promises'\nimport { resolve } from 'node:path'\nimport { pathToFileURL } from 'node:url'\nimport { defineCli, defineCommand } from 'hanzio/cli'\nimport { z } from 'zod'\nimport type { EvalCase } from './case.js'\nimport { type EvalConfig, runEvalSuite, selectCases } from './config.js'\nimport {\n\tcompareReports,\n\ttype EvalReport,\n\tformatModelComparison,\n\tformatReport\n} from './report.js'\n\nconst runInput = z.object({\n\tconfig: z.string().default('evals.config.ts').describe('Eval config module'),\n\tsuite: z.string().default('smoke').describe('Suite to run'),\n\tcase: z.array(z.string()).describe('Only cases whose id starts with this'),\n\ttag: z.string().optional().describe('Only cases with this tag'),\n\trepeats: z.number().default(3).describe('Runs per case'),\n\tconcurrency: z.number().default(3).describe('Cases in flight'),\n\tmodel: z\n\t\t.array(z.string())\n\t\t.describe('Model to run on; several print a comparison'),\n\tjudge: z.boolean().default(true).describe('Score runs with the config judge'),\n\tcompare: z.string().optional().describe('Baseline report to compare with'),\n\toutput: z\n\t\t.string()\n\t\t.optional()\n\t\t.describe('Report file to write; several models add -<model>'),\n\tverbose: z.boolean().describe('Keep app console logs')\n})\n\ntype RunInput = z.output<typeof runInput>\n\nasync function loadConfig(path: string): Promise<EvalConfig> {\n\tconst file = resolve(path)\n\tconst module = await import(pathToFileURL(file).href)\n\tif (!module.default) throw new Error(`${file} has no default export`)\n\treturn module.default\n}\n\nasync function readReport(file: string): Promise<EvalReport> {\n\treturn JSON.parse(await readFile(file, 'utf8'))\n}\n\n/** `--output` for one model, with the model before the extension when several run. */\nfunction outputFile(output: string, modelId: string, models: number) {\n\tif (models === 1) return resolve(output)\n\tconst model = modelId.replaceAll('/', '_')\n\tconst dot = output.lastIndexOf('.')\n\treturn resolve(\n\t\tdot > output.lastIndexOf('/')\n\t\t\t? `${output.slice(0, dot)}-${model}${output.slice(dot)}`\n\t\t\t: `${output}-${model}`\n\t)\n}\n\nasync function save(config: EvalConfig, report: EvalReport, output?: string) {\n\tif (output) {\n\t\tawait writeFile(output, `${JSON.stringify(report, null, '\\t')}\\n`)\n\t\treturn output\n\t}\n\tconst dir = resolve(config.outputDir ?? '.evals')\n\tawait mkdir(dir, { recursive: true })\n\tconst ignore = resolve(dir, '.gitignore')\n\tif (!(await stat(ignore).catch(() => null))) await writeFile(ignore, '*\\n')\n\tconst file = resolve(\n\t\tdir,\n\t\t`${report.startedAt.replaceAll(':', '-')}-${report.suite}-${report.modelId.replaceAll('/', '_')}.json`\n\t)\n\tawait writeFile(file, `${JSON.stringify(report, null, '\\t')}\\n`)\n\treturn file\n}\n\n/** Apps log to the console; while cases run that buries the progress lines. */\nfunction silenceLogs(verbose: boolean) {\n\tif (verbose) return () => {}\n\tconst { log, info, debug } = console\n\tconsole.log = console.info = console.debug = () => {}\n\treturn () => Object.assign(console, { log, info, debug })\n}\n\nasync function run(values: RunInput) {\n\tconst config = await loadConfig(values.config)\n\ttry {\n\t\treturn await runWith(config, values)\n\t} finally {\n\t\tawait config.teardown?.()\n\t}\n}\n\nasync function runWith(config: EvalConfig, values: RunInput) {\n\tawait config.setup?.()\n\tconst all =\n\t\ttypeof config.cases === 'function' ? await config.cases() : config.cases\n\tconst prefixes = values.case\n\tconst cases: readonly EvalCase<unknown>[] = selectCases(all, {\n\t\tsuite: values.suite,\n\t\tprefixes,\n\t\t...(values.tag ? { tag: values.tag } : {})\n\t})\n\tconst models = values.model.length ? values.model : [config.defaultModel]\n\tconst reports: EvalReport[] = []\n\tfor (const modelId of models) {\n\t\tconsole.error(\n\t\t\t`Running ${cases.length} cases x${values.repeats} on ${modelId}${config.judge && values.judge ? ', judged' : ''}`\n\t\t)\n\t\tconst restore = silenceLogs(values.verbose)\n\t\tconst report = await runEvalSuite(config, {\n\t\t\tcases,\n\t\t\tsuite: prefixes.length ? 'selected' : values.suite,\n\t\t\tmodelId,\n\t\t\trepeats: values.repeats,\n\t\t\tconcurrency: values.concurrency,\n\t\t\tjudge: values.judge,\n\t\t\tonRun: (testCase, result) =>\n\t\t\t\tconsole.error(`${result.pass ? 'pass' : 'FAIL'} ${testCase.id}`)\n\t\t}).finally(restore)\n\t\tconsole.log(formatReport(report))\n\t\tconst output =\n\t\t\tvalues.output && outputFile(values.output, modelId, models.length)\n\t\tconsole.log(`\\n${await save(config, report, output)}\\n`)\n\t\treports.push(report)\n\t}\n\tif (reports.length > 1) console.log(formatModelComparison(reports))\n\tconst [first, ...rest] = reports\n\tfor (const report of rest) {\n\t\tif (first) console.log(`\\n${compareReports(first, report)}`)\n\t}\n\tif (values.compare && first) {\n\t\tconsole.log(`\\n${compareReports(await readReport(values.compare), first)}`)\n\t}\n\tconst failed = reports.some((report) =>\n\t\treport.results.some((result) => result.runs.some((r) => !r.pass))\n\t)\n\treturn failed ? 1 : 0\n}\n\nfunction inspect(report: EvalReport, prefixes: readonly string[]) {\n\tfor (const result of report.results) {\n\t\tif (\n\t\t\tprefixes.length &&\n\t\t\t!prefixes.some((prefix) => result.caseId.startsWith(prefix))\n\t\t)\n\t\t\tcontinue\n\t\tresult.runs.forEach((run, index) => {\n\t\t\tconsole.log(\n\t\t\t\t`\\n=== ${result.caseId} #${index + 1} ${run.pass ? 'pass' : 'FAIL'}`\n\t\t\t)\n\t\t\tfor (const check of run.checks.filter((check) => !check.pass)) {\n\t\t\t\tconsole.log(\n\t\t\t\t\t` ✗ ${check.check}${check.detail ? ` (${check.detail})` : ''}`\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (run.verdict) console.log(` judge: ${JSON.stringify(run.verdict)}`)\n\t\t\tif (run.judgeError) console.log(` judge failed: ${run.judgeError}`)\n\t\t\tfor (const turn of run.trace.turns) {\n\t\t\t\tconsole.log(`\\n User: ${turn.userText}`)\n\t\t\t\tfor (const call of turn.toolCalls) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t` ${call.name} [${call.state}] ${JSON.stringify(call.input).slice(0, 200)}${call.errorText ? ` ERROR ${call.errorText}` : ''}`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tconsole.log(\n\t\t\t\t\t` Assistant (${turn.firstTextMs === null ? '-' : `${(turn.firstTextMs / 1000).toFixed(1)}s`}, ${turn.steps} steps): ${turn.replyText}`\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\t}\n}\n\nconst cli = defineCli({\n\tname: 'better-mastra-evals',\n\tdescription:\n\t\t\"Real turns through the app's production turn, scored by checks and a judge\",\n\t// `better-mastra-evals` alone, or with options first, runs `run`.\n\tdefaultCommand: 'run',\n\tcommands: {\n\t\trun: defineCommand({\n\t\t\tdescription: 'Run a suite and save its report',\n\t\t\tinput: runInput,\n\t\t\trun: async (input, ctx) => {\n\t\t\t\tctx.exitCode = await run(input)\n\t\t\t}\n\t\t}),\n\t\tinspect: defineCommand({\n\t\t\tdescription: \"Print a report's failed checks and transcripts\",\n\t\t\tinput: z.object({\n\t\t\t\treport: z.string().meta({ positional: true }).describe('Report file'),\n\t\t\t\tcase: z\n\t\t\t\t\t.array(z.string())\n\t\t\t\t\t.describe('Only cases whose id starts with this')\n\t\t\t}),\n\t\t\trun: async (input) => inspect(await readReport(input.report), input.case)\n\t\t}),\n\t\tcompare: defineCommand({\n\t\t\tdescription: 'Compare a candidate report with a baseline',\n\t\t\tinput: z.object({\n\t\t\t\tbaseline: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.meta({ positional: true })\n\t\t\t\t\t.describe('Baseline report file'),\n\t\t\t\tcandidate: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.meta({ positional: true })\n\t\t\t\t\t.describe('Candidate report file')\n\t\t\t}),\n\t\t\trun: async (input) =>\n\t\t\t\tcompareReports(\n\t\t\t\t\tawait readReport(input.baseline),\n\t\t\t\t\tawait readReport(input.candidate)\n\t\t\t\t)\n\t\t})\n\t}\n})\n\n// App pools (database, Redis) keep the event loop alive after the last run.\nprocess.exit(await cli.run())\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"defineTool.d.ts","sourceRoot":"","sources":["../../src/tools/defineTool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAK1D,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAA;AAGzD,KAAK,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAEtD,qGAAqG;AACrG,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;AAE1D,gGAAgG;AAChG,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAE1C,MAAM,WAAW,cAAc,CAC9B,KAAK,SAAS,QAAQ,GAAG,QAAQ,EACjC,KAAK,SAAS,MAAM,GAAG,MAAM;IAE7B,kDAAkD;IAClD,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,iBAAiB,CAAA;IAC1C,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;IACpB,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAA;IACrB,mEAAmE;IACnE,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,QAAQ,CAC/B,MAAM,CAAC,MAAM,EAAE,CAAC,cAAc,EAAE,cAAc,KAAK,OAAO,CAAC,CAC3D,CAAA;IACD,wEAAwE;IACxE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,qGAAqG;IACrG,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,KAAK,OAAO,CAAA;IACnD,4FAA4F;IAC5F,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CACrD;AAED,MAAM,WAAW,WAAW,CAC3B,KAAK,SAAS,QAAQ,GAAG,QAAQ,EACjC,KAAK,SAAS,MAAM,GAAG,MAAM;IAE7B,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,SAAS,CAAA;IAChC,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;IACvC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CACpD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACzB,KAAK,CAAC,KAAK,SAAS,QAAQ,EAC5B,KAAK,CAAC,KAAK,SAAS,MAAM,GAAG,SAAS,EACrC,UAAU,EAAE,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAyDrE;AAED,yFAAyF;AACzF,wBAAgB,SAAS,CAAC,WAAW,EAAE,SAAS,WAAW,EAAE,GAAG;IAC/D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC1C,CASA;AAED,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C"}
1
+ {"version":3,"file":"defineTool.d.ts","sourceRoot":"","sources":["../../src/tools/defineTool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAK1D,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAA;AAGzD,KAAK,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAEtD,qGAAqG;AACrG,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;AAE1D,gGAAgG;AAChG,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAE1C,MAAM,WAAW,cAAc,CAC9B,KAAK,SAAS,QAAQ,GAAG,QAAQ,EACjC,KAAK,SAAS,MAAM,GAAG,MAAM;IAE7B,kDAAkD;IAClD,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,iBAAiB,CAAA;IAC1C,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;IACpB,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAA;IACrB,mEAAmE;IACnE,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,QAAQ,CAC/B,MAAM,CAAC,MAAM,EAAE,CAAC,cAAc,EAAE,cAAc,KAAK,OAAO,CAAC,CAC3D,CAAA;IACD,wEAAwE;IACxE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,qGAAqG;IACrG,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,KAAK,OAAO,CAAA;IACnD,4FAA4F;IAC5F,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CACrD;AAED,MAAM,WAAW,WAAW,CAC3B,KAAK,SAAS,QAAQ,GAAG,QAAQ,EACjC,KAAK,SAAS,MAAM,GAAG,MAAM;IAE7B,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,SAAS,CAAA;IAChC,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;IACvC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CACpD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACzB,KAAK,CAAC,KAAK,SAAS,QAAQ,EAC5B,KAAK,CAAC,KAAK,SAAS,MAAM,GAAG,SAAS,EACrC,UAAU,EAAE,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAgErE;AAED,yFAAyF;AACzF,wBAAgB,SAAS,CAAC,WAAW,EAAE,SAAS,WAAW,EAAE,GAAG;IAC/D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC1C,CASA;AAED,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C"}
@@ -20,7 +20,13 @@ export function defineTool(definition) {
20
20
  : createTool(definition.tool);
21
21
  const hidden = definition.hiddenInputs ?? {};
22
22
  const hiddenNames = Object.keys(hidden);
23
- const baseExecute = base.execute;
23
+ // Mastra's tool validates its input before it calls the function it wraps.
24
+ // With hidden inputs that second pass is the only check of the filled
25
+ // values, so it stays; without them the outer tool already validated the
26
+ // same input, so the function the options name runs directly.
27
+ const baseExecute = hiddenNames.length === 0 && !isTool(definition.tool)
28
+ ? definition.tool.execute
29
+ : base.execute;
24
30
  const toModelOutput = definition.toModelOutput;
25
31
  // Only a read is safe to run in an eval's dry run.
26
32
  const honoursDryRun = definition.tier !== 'read';
@@ -1 +1 @@
1
- {"version":3,"file":"defineTool.js","sourceRoot":"","sources":["../../src/tools/defineTool.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * One definition per agent tool: the Mastra tool itself (made here with\n * `createTool`'s options, or made elsewhere, such as by orpc-fn's\n * `createMastraTool`) and what the chat knows about it: its tier, its card,\n * the data a write invalidates, the inputs the turn fills in from the request\n * context instead of the model, and the compact text the model reads. The\n * turn's tool set and the client's manifest both derive from these.\n */\n\nimport type { RequestContext } from '@mastra/core/request-context'\nimport { createTool, type Tool } from '@mastra/core/tools'\n\nimport { dryRunResult, isDryRun, isDryRunResult } from './dryRun.js'\nimport { withHiddenInputs } from './toolInputSchema.js'\n\ntype CreateToolOptions = Parameters<typeof createTool>[0]\n\n// biome-ignore lint/suspicious/noExplicitAny: any Mastra tool, whatever its schemas.\ntype AnyTool = Tool<any, any, any, any, any, any, any>\n\n/** A tier: `read` runs at once, `approval` waits for the user's approval. Apps may add their own. */\nexport type ToolTier = 'read' | 'approval' | (string & {})\n\n/** Where the tool runs: on the server, or without `execute` in the client (`addToolOutput`). */\nexport type ToolKind = 'server' | 'client'\n\nexport interface ToolDefinition<\n\tTTier extends ToolTier = ToolTier,\n\tTCard extends string = string\n> {\n\t/** The tool, or `createTool`'s options for it. */\n\treadonly tool: AnyTool | CreateToolOptions\n\treadonly tier: TTier\n\t/** How the client draws the result. Default `generic`. */\n\treadonly card?: TCard\n\t/** Data namespaces a write changes, which the client refetches. */\n\treadonly invalidates?: readonly string[]\n\t/**\n\t * Inputs the model never sees, filled in from the run's request context:\n\t * the value replaces anything the model sent. A value of undefined leaves\n\t * the input out.\n\t */\n\treadonly hiddenInputs?: Readonly<\n\t\tRecord<string, (requestContext: RequestContext) => unknown>\n\t>\n\t/** Caps every list in a write's input, so one change stays one Undo. */\n\treadonly maxArrayItems?: number\n\t/** The compact text the model reads instead of the full result; the client still gets the result. */\n\treadonly toModelOutput?: (output: never) => unknown\n\t/** JSON-only extras for the client manifest, such as how a confirm card shows the input. */\n\treadonly manifest?: Readonly<Record<string, unknown>>\n}\n\nexport interface DefinedTool<\n\tTTier extends ToolTier = ToolTier,\n\tTCard extends string = string\n> {\n\t/** The name the model, the stream and the manifest know the tool by. */\n\treadonly name: string\n\treadonly tool: AnyTool\n\treadonly kind: ToolKind\n\treadonly tier: TTier\n\treadonly card: TCard | 'generic'\n\treadonly invalidates: readonly string[]\n\treadonly manifest: Readonly<Record<string, unknown>>\n}\n\n/**\n * Declares one tool. Tier `approval` asks for approval before `execute`\n * runs; a tool without `execute` is a client tool. In a dry run\n * (`markDryRun`) a tool of any tier but `read` answers with a marker.\n */\nexport function defineTool<\n\tconst TTier extends ToolTier,\n\tconst TCard extends string = 'generic'\n>(definition: ToolDefinition<TTier, TCard>): DefinedTool<TTier, TCard> {\n\tconst base = isTool(definition.tool)\n\t\t? definition.tool\n\t\t: createTool(definition.tool)\n\tconst hidden = definition.hiddenInputs ?? {}\n\tconst hiddenNames = Object.keys(hidden)\n\tconst baseExecute = base.execute\n\tconst toModelOutput = definition.toModelOutput\n\t// Only a read is safe to run in an eval's dry run.\n\tconst honoursDryRun = definition.tier !== 'read'\n\n\tconst tool = createTool({\n\t\t...(base as CreateToolOptions),\n\t\t...(base.inputSchema &&\n\t\t\t(hiddenNames.length > 0 || definition.maxArrayItems !== undefined) && {\n\t\t\t\tinputSchema: withHiddenInputs(base.inputSchema, hiddenNames, {\n\t\t\t\t\tmaxArrayItems: definition.maxArrayItems\n\t\t\t\t})\n\t\t\t}),\n\t\trequireApproval:\n\t\t\tdefinition.tier === 'approval' || base.requireApproval === true,\n\t\t...(baseExecute && {\n\t\t\texecute: (\n\t\t\t\tinput: unknown,\n\t\t\t\tcontext: { requestContext?: RequestContext }\n\t\t\t) =>\n\t\t\t\thonoursDryRun && isDryRun(context?.requestContext)\n\t\t\t\t\t? dryRunResult(base.id)\n\t\t\t\t\t: baseExecute(\n\t\t\t\t\t\t\tfillHiddenInputs(input, hidden, context?.requestContext),\n\t\t\t\t\t\t\tcontext as never\n\t\t\t\t\t\t)\n\t\t}),\n\t\t...(toModelOutput && {\n\t\t\ttoModelOutput: (output: unknown) => {\n\t\t\t\tif (isDryRunResult(output)) {\n\t\t\t\t\treturn { type: 'text', value: JSON.stringify(output) }\n\t\t\t\t}\n\n\t\t\t\tconst model = toModelOutput(output as never)\n\n\t\t\t\treturn typeof model === 'string'\n\t\t\t\t\t? { type: 'text', value: model }\n\t\t\t\t\t: model\n\t\t\t}\n\t\t})\n\t} as CreateToolOptions) as AnyTool\n\n\treturn {\n\t\tname: tool.id,\n\t\ttool,\n\t\tkind: baseExecute ? 'server' : 'client',\n\t\ttier: definition.tier,\n\t\tcard: definition.card ?? 'generic',\n\t\tinvalidates: definition.invalidates ?? [],\n\t\tmanifest: definition.manifest ?? {}\n\t}\n}\n\n/** The Mastra tools of the definitions by name, and each one's tier, for a turn plan. */\nexport function toToolSet(definitions: readonly DefinedTool[]): {\n\treadonly tools: Record<string, AnyTool>\n\treadonly toolTiers: Record<string, string>\n} {\n\treturn {\n\t\ttools: Object.fromEntries(\n\t\t\tdefinitions.map((tool) => [tool.name, tool.tool])\n\t\t),\n\t\ttoolTiers: Object.fromEntries(\n\t\t\tdefinitions.map((tool) => [tool.name, tool.tier])\n\t\t)\n\t}\n}\n\n/** `budget.getBudget` becomes `budget_getBudget`, a name every provider accepts. */\nexport function toToolName(name: string): string {\n\treturn name.replaceAll('.', '_')\n}\n\nfunction fillHiddenInputs(\n\tinput: unknown,\n\thidden: Readonly<Record<string, (requestContext: RequestContext) => unknown>>,\n\trequestContext: RequestContext | undefined\n): unknown {\n\tconst names = Object.keys(hidden)\n\n\tif (names.length === 0) return input\n\n\tif (!requestContext) {\n\t\tthrow new Error('A tool with hidden inputs ran without a request context.')\n\t}\n\n\tconst visible = Object.fromEntries(\n\t\tObject.entries((input ?? {}) as Record<string, unknown>).filter(\n\t\t\t([key]) => !names.includes(key)\n\t\t)\n\t)\n\tconst filled = Object.fromEntries(\n\t\tnames.flatMap((name) => {\n\t\t\tconst value = hidden[name]?.(requestContext)\n\n\t\t\treturn value === undefined ? [] : [[name, value]]\n\t\t})\n\t)\n\n\treturn { ...visible, ...filled }\n}\n\n/** `createTool`'s options are a plain object; a tool is a class instance, from whichever copy of Mastra made it. */\nfunction isTool(value: AnyTool | CreateToolOptions): value is AnyTool {\n\treturn Object.getPrototypeOf(value) !== Object.prototype\n}\n"]}
1
+ {"version":3,"file":"defineTool.js","sourceRoot":"","sources":["../../src/tools/defineTool.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * One definition per agent tool: the Mastra tool itself (made here with\n * `createTool`'s options, or made elsewhere, such as by orpc-fn's\n * `createMastraTool`) and what the chat knows about it: its tier, its card,\n * the data a write invalidates, the inputs the turn fills in from the request\n * context instead of the model, and the compact text the model reads. The\n * turn's tool set and the client's manifest both derive from these.\n */\n\nimport type { RequestContext } from '@mastra/core/request-context'\nimport { createTool, type Tool } from '@mastra/core/tools'\n\nimport { dryRunResult, isDryRun, isDryRunResult } from './dryRun.js'\nimport { withHiddenInputs } from './toolInputSchema.js'\n\ntype CreateToolOptions = Parameters<typeof createTool>[0]\n\n// biome-ignore lint/suspicious/noExplicitAny: any Mastra tool, whatever its schemas.\ntype AnyTool = Tool<any, any, any, any, any, any, any>\n\n/** A tier: `read` runs at once, `approval` waits for the user's approval. Apps may add their own. */\nexport type ToolTier = 'read' | 'approval' | (string & {})\n\n/** Where the tool runs: on the server, or without `execute` in the client (`addToolOutput`). */\nexport type ToolKind = 'server' | 'client'\n\nexport interface ToolDefinition<\n\tTTier extends ToolTier = ToolTier,\n\tTCard extends string = string\n> {\n\t/** The tool, or `createTool`'s options for it. */\n\treadonly tool: AnyTool | CreateToolOptions\n\treadonly tier: TTier\n\t/** How the client draws the result. Default `generic`. */\n\treadonly card?: TCard\n\t/** Data namespaces a write changes, which the client refetches. */\n\treadonly invalidates?: readonly string[]\n\t/**\n\t * Inputs the model never sees, filled in from the run's request context:\n\t * the value replaces anything the model sent. A value of undefined leaves\n\t * the input out.\n\t */\n\treadonly hiddenInputs?: Readonly<\n\t\tRecord<string, (requestContext: RequestContext) => unknown>\n\t>\n\t/** Caps every list in a write's input, so one change stays one Undo. */\n\treadonly maxArrayItems?: number\n\t/** The compact text the model reads instead of the full result; the client still gets the result. */\n\treadonly toModelOutput?: (output: never) => unknown\n\t/** JSON-only extras for the client manifest, such as how a confirm card shows the input. */\n\treadonly manifest?: Readonly<Record<string, unknown>>\n}\n\nexport interface DefinedTool<\n\tTTier extends ToolTier = ToolTier,\n\tTCard extends string = string\n> {\n\t/** The name the model, the stream and the manifest know the tool by. */\n\treadonly name: string\n\treadonly tool: AnyTool\n\treadonly kind: ToolKind\n\treadonly tier: TTier\n\treadonly card: TCard | 'generic'\n\treadonly invalidates: readonly string[]\n\treadonly manifest: Readonly<Record<string, unknown>>\n}\n\n/**\n * Declares one tool. Tier `approval` asks for approval before `execute`\n * runs; a tool without `execute` is a client tool. In a dry run\n * (`markDryRun`) a tool of any tier but `read` answers with a marker.\n */\nexport function defineTool<\n\tconst TTier extends ToolTier,\n\tconst TCard extends string = 'generic'\n>(definition: ToolDefinition<TTier, TCard>): DefinedTool<TTier, TCard> {\n\tconst base = isTool(definition.tool)\n\t\t? definition.tool\n\t\t: createTool(definition.tool)\n\tconst hidden = definition.hiddenInputs ?? {}\n\tconst hiddenNames = Object.keys(hidden)\n\t// Mastra's tool validates its input before it calls the function it wraps.\n\t// With hidden inputs that second pass is the only check of the filled\n\t// values, so it stays; without them the outer tool already validated the\n\t// same input, so the function the options name runs directly.\n\tconst baseExecute =\n\t\thiddenNames.length === 0 && !isTool(definition.tool)\n\t\t\t? definition.tool.execute\n\t\t\t: base.execute\n\tconst toModelOutput = definition.toModelOutput\n\t// Only a read is safe to run in an eval's dry run.\n\tconst honoursDryRun = definition.tier !== 'read'\n\n\tconst tool = createTool({\n\t\t...(base as CreateToolOptions),\n\t\t...(base.inputSchema &&\n\t\t\t(hiddenNames.length > 0 || definition.maxArrayItems !== undefined) && {\n\t\t\t\tinputSchema: withHiddenInputs(base.inputSchema, hiddenNames, {\n\t\t\t\t\tmaxArrayItems: definition.maxArrayItems\n\t\t\t\t})\n\t\t\t}),\n\t\trequireApproval:\n\t\t\tdefinition.tier === 'approval' || base.requireApproval === true,\n\t\t...(baseExecute && {\n\t\t\texecute: (\n\t\t\t\tinput: unknown,\n\t\t\t\tcontext: { requestContext?: RequestContext }\n\t\t\t) =>\n\t\t\t\thonoursDryRun && isDryRun(context?.requestContext)\n\t\t\t\t\t? dryRunResult(base.id)\n\t\t\t\t\t: baseExecute(\n\t\t\t\t\t\t\tfillHiddenInputs(input, hidden, context?.requestContext),\n\t\t\t\t\t\t\tcontext as never\n\t\t\t\t\t\t)\n\t\t}),\n\t\t...(toModelOutput && {\n\t\t\ttoModelOutput: (output: unknown) => {\n\t\t\t\tif (isDryRunResult(output)) {\n\t\t\t\t\treturn { type: 'text', value: JSON.stringify(output) }\n\t\t\t\t}\n\n\t\t\t\tconst model = toModelOutput(output as never)\n\n\t\t\t\treturn typeof model === 'string'\n\t\t\t\t\t? { type: 'text', value: model }\n\t\t\t\t\t: model\n\t\t\t}\n\t\t})\n\t} as CreateToolOptions) as AnyTool\n\n\treturn {\n\t\tname: tool.id,\n\t\ttool,\n\t\tkind: baseExecute ? 'server' : 'client',\n\t\ttier: definition.tier,\n\t\tcard: definition.card ?? 'generic',\n\t\tinvalidates: definition.invalidates ?? [],\n\t\tmanifest: definition.manifest ?? {}\n\t}\n}\n\n/** The Mastra tools of the definitions by name, and each one's tier, for a turn plan. */\nexport function toToolSet(definitions: readonly DefinedTool[]): {\n\treadonly tools: Record<string, AnyTool>\n\treadonly toolTiers: Record<string, string>\n} {\n\treturn {\n\t\ttools: Object.fromEntries(\n\t\t\tdefinitions.map((tool) => [tool.name, tool.tool])\n\t\t),\n\t\ttoolTiers: Object.fromEntries(\n\t\t\tdefinitions.map((tool) => [tool.name, tool.tier])\n\t\t)\n\t}\n}\n\n/** `budget.getBudget` becomes `budget_getBudget`, a name every provider accepts. */\nexport function toToolName(name: string): string {\n\treturn name.replaceAll('.', '_')\n}\n\nfunction fillHiddenInputs(\n\tinput: unknown,\n\thidden: Readonly<Record<string, (requestContext: RequestContext) => unknown>>,\n\trequestContext: RequestContext | undefined\n): unknown {\n\tconst names = Object.keys(hidden)\n\n\tif (names.length === 0) return input\n\n\tif (!requestContext) {\n\t\tthrow new Error('A tool with hidden inputs ran without a request context.')\n\t}\n\n\tconst visible = Object.fromEntries(\n\t\tObject.entries((input ?? {}) as Record<string, unknown>).filter(\n\t\t\t([key]) => !names.includes(key)\n\t\t)\n\t)\n\tconst filled = Object.fromEntries(\n\t\tnames.flatMap((name) => {\n\t\t\tconst value = hidden[name]?.(requestContext)\n\n\t\t\treturn value === undefined ? [] : [[name, value]]\n\t\t})\n\t)\n\n\treturn { ...visible, ...filled }\n}\n\n/** `createTool`'s options are a plain object; a tool is a class instance, from whichever copy of Mastra made it. */\nfunction isTool(value: AnyTool | CreateToolOptions): value is AnyTool {\n\treturn Object.getPrototypeOf(value) !== Object.prototype\n}\n"]}
@@ -4,18 +4,34 @@
4
4
  * itself, so a client bundle never imports server code.
5
5
  */
6
6
  import type { DefinedTool, ToolKind } from './defineTool.js';
7
- export interface ToolManifestEntry {
8
- readonly kind: ToolKind;
7
+ export interface ToolManifestEntry<TKind extends string = ToolKind> {
8
+ readonly kind: TKind;
9
9
  readonly tier: string;
10
10
  readonly card: string;
11
11
  readonly invalidates: readonly string[];
12
12
  readonly [extra: string]: unknown;
13
13
  }
14
- export type ToolManifest = Readonly<Record<string, ToolManifestEntry>>;
15
- /** The manifest of the definitions, in their order. */
16
- export declare function buildToolManifest(definitions: readonly DefinedTool[]): ToolManifest;
17
- /** The source of a generated manifest module, which a client imports without the tools. */
18
- export declare function renderToolManifestSource(manifest: ToolManifest, options?: {
14
+ export type ToolManifest<TKind extends string = ToolKind> = Readonly<Record<string, ToolManifestEntry<TKind>>>;
15
+ /**
16
+ * The manifest of the definitions, in their order. `kind` names each tool's
17
+ * kind in the app's own words; default `server` or `client`.
18
+ */
19
+ export declare function buildToolManifest<TKind extends string = ToolKind>(definitions: readonly DefinedTool[], options?: {
20
+ readonly kind?: (definition: DefinedTool) => TKind;
21
+ }): ToolManifest<TKind>;
22
+ /**
23
+ * The source of a generated manifest module, which a client imports without
24
+ * the tools, written as Biome writes it with single quotes and no
25
+ * semicolons. With `type` the export is annotated with the app's manifest
26
+ * type; without it the object is `as const`.
27
+ */
28
+ export declare function renderToolManifestSource(manifest: ToolManifest<string>, options?: {
19
29
  readonly exportName?: string;
30
+ readonly type?: {
31
+ readonly name: string;
32
+ readonly from: string;
33
+ };
34
+ /** The command that wrote it, for the header. */
35
+ readonly generatedBy?: string;
20
36
  }): string;
21
37
  //# sourceMappingURL=manifest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/tools/manifest.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAE5D,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;IACvC,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;CACjC;AAED,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAA;AAEtE,uDAAuD;AACvD,wBAAgB,iBAAiB,CAChC,WAAW,EAAE,SAAS,WAAW,EAAE,GACjC,YAAY,CAad;AAED,2FAA2F;AAC3F,wBAAgB,wBAAwB,CACvC,QAAQ,EAAE,YAAY,EACtB,OAAO,GAAE;IAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5C,MAAM,CAYR"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/tools/manifest.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAE5D,MAAM,WAAW,iBAAiB,CAAC,KAAK,SAAS,MAAM,GAAG,QAAQ;IACjE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;IACvC,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;CACjC;AAED,MAAM,MAAM,YAAY,CAAC,KAAK,SAAS,MAAM,GAAG,QAAQ,IAAI,QAAQ,CACnE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC,CACxC,CAAA;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,SAAS,MAAM,GAAG,QAAQ,EAChE,WAAW,EAAE,SAAS,WAAW,EAAE,EACnC,OAAO,GAAE;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,WAAW,KAAK,KAAK,CAAA;CAAO,GAClE,YAAY,CAAC,KAAK,CAAC,CAarB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACvC,QAAQ,EAAE,YAAY,CAAC,MAAM,CAAC,EAC9B,OAAO,GAAE;IACR,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAChE,iDAAiD;IACjD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CACxB,GACJ,MAAM,CAmBR"}
@@ -3,30 +3,90 @@
3
3
  * tier, card, the data it invalidates and its own extras, without the tool
4
4
  * itself, so a client bundle never imports server code.
5
5
  */
6
- /** The manifest of the definitions, in their order. */
7
- export function buildToolManifest(definitions) {
6
+ /**
7
+ * The manifest of the definitions, in their order. `kind` names each tool's
8
+ * kind in the app's own words; default `server` or `client`.
9
+ */
10
+ export function buildToolManifest(definitions, options = {}) {
8
11
  return Object.fromEntries(definitions.map((definition) => [
9
12
  definition.name,
10
13
  {
11
14
  ...definition.manifest,
12
- kind: definition.kind,
15
+ kind: options.kind?.(definition) ?? definition.kind,
13
16
  tier: definition.tier,
14
17
  card: definition.card,
15
18
  invalidates: definition.invalidates
16
19
  }
17
20
  ]));
18
21
  }
19
- /** The source of a generated manifest module, which a client imports without the tools. */
22
+ /**
23
+ * The source of a generated manifest module, which a client imports without
24
+ * the tools, written as Biome writes it with single quotes and no
25
+ * semicolons. With `type` the export is annotated with the app's manifest
26
+ * type; without it the object is `as const`.
27
+ */
20
28
  export function renderToolManifestSource(manifest, options = {}) {
21
29
  const exportName = options.exportName ?? 'toolManifest';
30
+ const value = renderValue(manifest, 0, exportName.length + 16);
22
31
  return [
23
32
  '/**',
24
33
  ' * The tool manifest, generated from the tool definitions by',
25
- ' * `better-mastra-tool-manifest`. Do not edit it by hand.',
34
+ ` * \`${options.generatedBy ?? 'better-mastra-tool-manifest'}\`. Do not edit it by hand.`,
26
35
  ' */',
27
36
  '',
28
- `export const ${exportName} = ${JSON.stringify(manifest, null, '\t')} as const`,
37
+ ...(options.type
38
+ ? [
39
+ `import type { ${options.type.name} } from '${options.type.from}'`,
40
+ '',
41
+ `export const ${exportName}: ${options.type.name} = ${value}`
42
+ ]
43
+ : [`export const ${exportName} = ${value} as const`]),
29
44
  ''
30
45
  ].join('\n');
31
46
  }
47
+ const LINE_WIDTH = 80;
48
+ const TAB_WIDTH = 2;
49
+ const IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
50
+ /** `used` is the width of the line before the value, for a list that may fit on it. */
51
+ function renderValue(value, depth, used) {
52
+ if (Array.isArray(value))
53
+ return renderArray(value, depth, used);
54
+ if (typeof value === 'object' && value !== null) {
55
+ return renderObject(value, depth);
56
+ }
57
+ return typeof value === 'string' ? quote(value) : String(value ?? 'undefined');
58
+ }
59
+ // An object stays expanded, as Biome keeps one whose first key starts a line.
60
+ function renderObject(value, depth) {
61
+ const entries = Object.entries(value).filter(([, item]) => item !== undefined);
62
+ if (entries.length === 0)
63
+ return '{}';
64
+ const indent = '\t'.repeat(depth + 1);
65
+ const lines = entries.map(([key, item]) => {
66
+ const name = IDENTIFIER.test(key) ? key : quote(key);
67
+ const used = (depth + 1) * TAB_WIDTH + name.length + 2;
68
+ return `${indent}${name}: ${renderValue(item, depth + 1, used)}`;
69
+ });
70
+ return `{\n${lines.join(',\n')}\n${'\t'.repeat(depth)}}`;
71
+ }
72
+ // A list of plain values fits on one line when Biome would keep it there.
73
+ function renderArray(value, depth, used) {
74
+ if (value.length === 0)
75
+ return '[]';
76
+ const isFlat = value.every((item) => typeof item !== 'object' || item === null);
77
+ const inline = `[${value.map((item) => renderValue(item, depth, 0)).join(', ')}]`;
78
+ // The comma after the value, as the entry is not the last, counts too.
79
+ if (isFlat && used + inline.length + 1 <= LINE_WIDTH)
80
+ return inline;
81
+ const indent = '\t'.repeat(depth + 1);
82
+ const lines = value.map((item) => `${indent}${renderValue(item, depth + 1, (depth + 1) * TAB_WIDTH)}`);
83
+ return `[\n${lines.join(',\n')}\n${'\t'.repeat(depth)}]`;
84
+ }
85
+ function quote(text) {
86
+ const escaped = JSON.stringify(text)
87
+ .slice(1, -1)
88
+ .replaceAll('\\"', '"')
89
+ .replaceAll("'", "\\'");
90
+ return `'${escaped}'`;
91
+ }
32
92
  //# sourceMappingURL=manifest.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/tools/manifest.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH,uDAAuD;AACvD,MAAM,UAAU,iBAAiB,CAChC,WAAmC;IAEnC,OAAO,MAAM,CAAC,WAAW,CACxB,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC;QAC/B,UAAU,CAAC,IAAI;QACf;YACC,GAAG,UAAU,CAAC,QAAQ;YACtB,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,WAAW,EAAE,UAAU,CAAC,WAAW;SACnC;KACD,CAAC,CACF,CAAA;AACF,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,wBAAwB,CACvC,QAAsB,EACtB,UAA4C,EAAE;IAE9C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,cAAc,CAAA;IAEvD,OAAO;QACN,KAAK;QACL,8DAA8D;QAC9D,2DAA2D;QAC3D,KAAK;QACL,EAAE;QACF,gBAAgB,UAAU,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW;QAC/E,EAAE;KACF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACb,CAAC","sourcesContent":["/**\n * The tool manifest the client reads: every tool by name with its kind,\n * tier, card, the data it invalidates and its own extras, without the tool\n * itself, so a client bundle never imports server code.\n */\n\nimport type { DefinedTool, ToolKind } from './defineTool.js'\n\nexport interface ToolManifestEntry {\n\treadonly kind: ToolKind\n\treadonly tier: string\n\treadonly card: string\n\treadonly invalidates: readonly string[]\n\treadonly [extra: string]: unknown\n}\n\nexport type ToolManifest = Readonly<Record<string, ToolManifestEntry>>\n\n/** The manifest of the definitions, in their order. */\nexport function buildToolManifest(\n\tdefinitions: readonly DefinedTool[]\n): ToolManifest {\n\treturn Object.fromEntries(\n\t\tdefinitions.map((definition) => [\n\t\t\tdefinition.name,\n\t\t\t{\n\t\t\t\t...definition.manifest,\n\t\t\t\tkind: definition.kind,\n\t\t\t\ttier: definition.tier,\n\t\t\t\tcard: definition.card,\n\t\t\t\tinvalidates: definition.invalidates\n\t\t\t}\n\t\t])\n\t)\n}\n\n/** The source of a generated manifest module, which a client imports without the tools. */\nexport function renderToolManifestSource(\n\tmanifest: ToolManifest,\n\toptions: { readonly exportName?: string } = {}\n): string {\n\tconst exportName = options.exportName ?? 'toolManifest'\n\n\treturn [\n\t\t'/**',\n\t\t' * The tool manifest, generated from the tool definitions by',\n\t\t' * `better-mastra-tool-manifest`. Do not edit it by hand.',\n\t\t' */',\n\t\t'',\n\t\t`export const ${exportName} = ${JSON.stringify(manifest, null, '\\t')} as const`,\n\t\t''\n\t].join('\\n')\n}\n"]}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/tools/manifest.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The tool manifest the client reads: every tool by name with its kind,\n * tier, card, the data it invalidates and its own extras, without the tool\n * itself, so a client bundle never imports server code.\n */\n\nimport type { DefinedTool, ToolKind } from './defineTool.js'\n\nexport interface ToolManifestEntry<TKind extends string = ToolKind> {\n\treadonly kind: TKind\n\treadonly tier: string\n\treadonly card: string\n\treadonly invalidates: readonly string[]\n\treadonly [extra: string]: unknown\n}\n\nexport type ToolManifest<TKind extends string = ToolKind> = Readonly<\n\tRecord<string, ToolManifestEntry<TKind>>\n>\n\n/**\n * The manifest of the definitions, in their order. `kind` names each tool's\n * kind in the app's own words; default `server` or `client`.\n */\nexport function buildToolManifest<TKind extends string = ToolKind>(\n\tdefinitions: readonly DefinedTool[],\n\toptions: { readonly kind?: (definition: DefinedTool) => TKind } = {}\n): ToolManifest<TKind> {\n\treturn Object.fromEntries(\n\t\tdefinitions.map((definition) => [\n\t\t\tdefinition.name,\n\t\t\t{\n\t\t\t\t...definition.manifest,\n\t\t\t\tkind: options.kind?.(definition) ?? (definition.kind as TKind),\n\t\t\t\ttier: definition.tier,\n\t\t\t\tcard: definition.card,\n\t\t\t\tinvalidates: definition.invalidates\n\t\t\t}\n\t\t])\n\t)\n}\n\n/**\n * The source of a generated manifest module, which a client imports without\n * the tools, written as Biome writes it with single quotes and no\n * semicolons. With `type` the export is annotated with the app's manifest\n * type; without it the object is `as const`.\n */\nexport function renderToolManifestSource(\n\tmanifest: ToolManifest<string>,\n\toptions: {\n\t\treadonly exportName?: string\n\t\treadonly type?: { readonly name: string; readonly from: string }\n\t\t/** The command that wrote it, for the header. */\n\t\treadonly generatedBy?: string\n\t} = {}\n): string {\n\tconst exportName = options.exportName ?? 'toolManifest'\n\tconst value = renderValue(manifest, 0, exportName.length + 16)\n\n\treturn [\n\t\t'/**',\n\t\t' * The tool manifest, generated from the tool definitions by',\n\t\t` * \\`${options.generatedBy ?? 'better-mastra-tool-manifest'}\\`. Do not edit it by hand.`,\n\t\t' */',\n\t\t'',\n\t\t...(options.type\n\t\t\t? [\n\t\t\t\t\t`import type { ${options.type.name} } from '${options.type.from}'`,\n\t\t\t\t\t'',\n\t\t\t\t\t`export const ${exportName}: ${options.type.name} = ${value}`\n\t\t\t\t]\n\t\t\t: [`export const ${exportName} = ${value} as const`]),\n\t\t''\n\t].join('\\n')\n}\n\nconst LINE_WIDTH = 80\nconst TAB_WIDTH = 2\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/\n\n/** `used` is the width of the line before the value, for a list that may fit on it. */\nfunction renderValue(value: unknown, depth: number, used: number): string {\n\tif (Array.isArray(value)) return renderArray(value, depth, used)\n\n\tif (typeof value === 'object' && value !== null) {\n\t\treturn renderObject(value as Record<string, unknown>, depth)\n\t}\n\n\treturn typeof value === 'string' ? quote(value) : String(value ?? 'undefined')\n}\n\n// An object stays expanded, as Biome keeps one whose first key starts a line.\nfunction renderObject(value: Record<string, unknown>, depth: number): string {\n\tconst entries = Object.entries(value).filter(([, item]) => item !== undefined)\n\n\tif (entries.length === 0) return '{}'\n\n\tconst indent = '\\t'.repeat(depth + 1)\n\tconst lines = entries.map(([key, item]) => {\n\t\tconst name = IDENTIFIER.test(key) ? key : quote(key)\n\t\tconst used = (depth + 1) * TAB_WIDTH + name.length + 2\n\n\t\treturn `${indent}${name}: ${renderValue(item, depth + 1, used)}`\n\t})\n\n\treturn `{\\n${lines.join(',\\n')}\\n${'\\t'.repeat(depth)}}`\n}\n\n// A list of plain values fits on one line when Biome would keep it there.\nfunction renderArray(\n\tvalue: readonly unknown[],\n\tdepth: number,\n\tused: number\n): string {\n\tif (value.length === 0) return '[]'\n\n\tconst isFlat = value.every(\n\t\t(item) => typeof item !== 'object' || item === null\n\t)\n\tconst inline = `[${value.map((item) => renderValue(item, depth, 0)).join(', ')}]`\n\n\t// The comma after the value, as the entry is not the last, counts too.\n\tif (isFlat && used + inline.length + 1 <= LINE_WIDTH) return inline\n\n\tconst indent = '\\t'.repeat(depth + 1)\n\tconst lines = value.map(\n\t\t(item) =>\n\t\t\t`${indent}${renderValue(item, depth + 1, (depth + 1) * TAB_WIDTH)}`\n\t)\n\n\treturn `[\\n${lines.join(',\\n')}\\n${'\\t'.repeat(depth)}]`\n}\n\nfunction quote(text: string): string {\n\tconst escaped = JSON.stringify(text)\n\t\t.slice(1, -1)\n\t\t.replaceAll('\\\\\"', '\"')\n\t\t.replaceAll(\"'\", \"\\\\'\")\n\n\treturn `'${escaped}'`\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"toolInputSchema.d.ts","sourceRoot":"","sources":["../../src/tools/toolInputSchema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AACjE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAevB,4FAA4F;AAC5F,MAAM,MAAM,eAAe,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAA;AAK7D;;;;GAIG;AACH,wBAAgB,eAAe,CAC9B,MAAM,EAAE,CAAC,CAAC,OAAO,EACjB,OAAO,GAAE;IAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAO,GAC3D,eAAe,CAwBjB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC/B,MAAM,EAAE,eAAe,EACvB,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,OAAO,GAAE;IAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAO,GAC3D,eAAe,CAsCjB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAChC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,EACvB,KAAK,EAAE,OAAO,GACZ,OAAO,CAsCT"}
1
+ {"version":3,"file":"toolInputSchema.d.ts","sourceRoot":"","sources":["../../src/tools/toolInputSchema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AACjE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAevB,4FAA4F;AAC5F,MAAM,MAAM,eAAe,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAA;AAK7D;;;;GAIG;AACH,wBAAgB,eAAe,CAC9B,MAAM,EAAE,CAAC,CAAC,OAAO,EACjB,OAAO,GAAE;IAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAO,GAC3D,eAAe,CAwBjB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC/B,MAAM,EAAE,eAAe,EACvB,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,OAAO,GAAE;IAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAO,GAC3D,eAAe,CA0CjB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAChC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,EACvB,KAAK,EAAE,OAAO,GACZ,OAAO,CAsCT"}
@@ -50,9 +50,11 @@ export function withHiddenInputs(schema, hiddenInputs, options = {}) {
50
50
  validate: (value) => {
51
51
  const input = withoutKeys(value, hiddenInputs);
52
52
  const finish = (result) => {
53
+ const own = (result.issues ?? []).filter((issue) => !isHiddenInputIssue(issue, hiddenInputs));
54
+ // A schema from `toolInputSchema` with the same cap already reported the list.
53
55
  const issues = [
54
- ...(result.issues ?? []).filter((issue) => !isHiddenInputIssue(issue, hiddenInputs)),
55
- ...findOverlongLists(input, options.maxArrayItems, [])
56
+ ...own,
57
+ ...findOverlongLists(input, options.maxArrayItems, []).filter((issue) => !own.some((reported) => isSameIssue(reported, issue)))
56
58
  ];
57
59
  if (issues.length > 0)
58
60
  return { issues };
@@ -202,4 +204,8 @@ function toUtcDatetime(value) {
202
204
  function isPlainObject(value) {
203
205
  return typeof value === 'object' && value !== null && !Array.isArray(value);
204
206
  }
207
+ function isSameIssue(left, right) {
208
+ return (left.message === right.message &&
209
+ JSON.stringify(left.path ?? []) === JSON.stringify(right.path ?? []));
210
+ }
205
211
  //# sourceMappingURL=toolInputSchema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"toolInputSchema.js","sourceRoot":"","sources":["../../src/tools/toolInputSchema.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tool input schemas as Mastra takes them (a Standard Schema with JSON Schema\n * attached): a zod input described with every date as an ISO string, and any\n * schema with its hidden inputs removed. Validation checks the model's input\n * with the original schema but hands the raw input on, so a procedure parses\n * and transforms it once.\n */\n\nimport type { StandardSchemaWithJSON } from '@mastra/core/schema'\nimport { z } from 'zod'\n\ntype JsonSchema = Record<string, unknown>\n\ninterface ValidationIssue {\n\treadonly message: string\n\treadonly path?:\n\t\t| ReadonlyArray<PropertyKey | { readonly key: PropertyKey }>\n\t\t| undefined\n}\n\ntype ValidationResult =\n\t| { readonly value: unknown; readonly issues?: undefined }\n\t| { readonly issues: readonly ValidationIssue[]; readonly value?: undefined }\n\n/** A Standard Schema with JSON Schema attached, the form Mastra accepts as a tool input. */\nexport type ToolInputSchema = StandardSchemaWithJSON<unknown>\n\n/** An ISO datetime that ends in an offset such as `+02:00`, or in no zone at all, not `Z`. */\nconst NON_UTC_DATETIME = /^\\d{4}-\\d{2}-\\d{2}T[\\d:.]+(?:[+-]\\d{2}:?\\d{2})?$/\n\n/**\n * A zod object input as a tool input: `z.date()` offered as an ISO string and\n * coerced back before validation, and with `maxArrayItems` every list capped.\n * Throws for an input that is not an object, a programming error.\n */\nexport function toolInputSchema(\n\tschema: z.ZodType,\n\toptions: { readonly maxArrayItems?: number | undefined } = {}\n): ToolInputSchema {\n\tconst jsonSchema = toToolJsonSchema(schema, options.maxArrayItems)\n\n\tif (jsonSchema.type !== 'object') {\n\t\tthrow new Error('A tool must take an object input.')\n\t}\n\n\treturn standardSchema(jsonSchema, (value) => {\n\t\tconst input = coerceDateStrings(schema, value)\n\t\tconst result = schema['~standard'].validate(input) as\n\t\t\t| ValidationResult\n\t\t\t| Promise<ValidationResult>\n\n\t\tif (result instanceof Promise) {\n\t\t\tthrow new Error('A tool input must validate synchronously.')\n\t\t}\n\n\t\tconst issues = [\n\t\t\t...(result.issues ?? []),\n\t\t\t...findOverlongLists(input, options.maxArrayItems, [])\n\t\t]\n\n\t\treturn issues.length > 0 ? { issues } : { value: input }\n\t})\n}\n\n/**\n * The schema without the hidden inputs: the model neither sees nor sends\n * them. One the model sends is dropped, and an issue about one is left for\n * the tool, which receives the turn's value.\n */\nexport function withHiddenInputs(\n\tschema: ToolInputSchema,\n\thiddenInputs: readonly string[],\n\toptions: { readonly maxArrayItems?: number | undefined } = {}\n): ToolInputSchema {\n\tconst visible = (jsonSchema: JsonSchema) =>\n\t\twithoutHiddenProperties(jsonSchema, hiddenInputs)\n\n\tconst own = schema['~standard']\n\n\treturn {\n\t\t'~standard': {\n\t\t\tversion: 1,\n\t\t\tvendor: own.vendor,\n\t\t\tjsonSchema: {\n\t\t\t\tinput: (jsonOptions) => visible(own.jsonSchema.input(jsonOptions)),\n\t\t\t\toutput: (jsonOptions) => visible(own.jsonSchema.output(jsonOptions))\n\t\t\t},\n\t\t\tvalidate: (value) => {\n\t\t\t\tconst input = withoutKeys(value, hiddenInputs)\n\t\t\t\tconst finish = (result: ValidationResult): ValidationResult => {\n\t\t\t\t\tconst issues = [\n\t\t\t\t\t\t...(result.issues ?? []).filter(\n\t\t\t\t\t\t\t(issue) => !isHiddenInputIssue(issue, hiddenInputs)\n\t\t\t\t\t\t),\n\t\t\t\t\t\t...findOverlongLists(input, options.maxArrayItems, [])\n\t\t\t\t\t]\n\n\t\t\t\t\tif (issues.length > 0) return { issues }\n\n\t\t\t\t\treturn { value: result.issues ? input : result.value }\n\t\t\t\t}\n\t\t\t\tconst result = own.validate(input) as\n\t\t\t\t\t| ValidationResult\n\t\t\t\t\t| Promise<ValidationResult>\n\n\t\t\t\treturn (\n\t\t\t\t\tresult instanceof Promise ? result.then(finish) : finish(result)\n\t\t\t\t) as ReturnType<typeof own.validate>\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * The input with each ISO string a `z.date()` field takes turned into a\n * `Date`, and a datetime with an offset or no zone turned into UTC where\n * `z.string().datetime()` refuses offsets. A `Date` stays as it is, so an\n * approved call that comes back from the run's snapshot as JSON passes again.\n */\nexport function coerceDateStrings(\n\tschema: z.core.$ZodType,\n\tvalue: unknown\n): unknown {\n\tconst def = (schema as z.core.$ZodTypes)._zod.def\n\n\tswitch (def.type) {\n\t\tcase 'date':\n\t\t\treturn typeof value === 'string' && !def.coerce ? new Date(value) : value\n\t\tcase 'string':\n\t\t\treturn typeof value === 'string' && refusesOffsets(def)\n\t\t\t\t? toUtcDatetime(value)\n\t\t\t\t: value\n\t\tcase 'optional':\n\t\tcase 'nullable':\n\t\tcase 'default':\n\t\tcase 'prefault':\n\t\tcase 'readonly':\n\t\t\treturn value === undefined || value === null\n\t\t\t\t? value\n\t\t\t\t: coerceDateStrings(def.innerType, value)\n\t\tcase 'object':\n\t\t\treturn isPlainObject(value)\n\t\t\t\t? Object.fromEntries(\n\t\t\t\t\t\tObject.entries(value).map(([key, field]) => {\n\t\t\t\t\t\t\tconst fieldSchema = def.shape[key]\n\n\t\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\t\tfieldSchema ? coerceDateStrings(fieldSchema, field) : field\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t: value\n\t\tcase 'array':\n\t\t\treturn Array.isArray(value)\n\t\t\t\t? value.map((item) => coerceDateStrings(def.element, item))\n\t\t\t\t: value\n\t\tdefault:\n\t\t\treturn value\n\t}\n}\n\nfunction standardSchema(\n\tjsonSchema: JsonSchema,\n\tvalidate: (value: unknown) => ValidationResult\n): ToolInputSchema {\n\treturn {\n\t\t'~standard': {\n\t\t\tversion: 1,\n\t\t\tvendor: 'better-mastra',\n\t\t\tvalidate: validate as ToolInputSchema['~standard']['validate'],\n\t\t\tjsonSchema: { input: () => jsonSchema, output: () => jsonSchema }\n\t\t}\n\t}\n}\n\n// Zod's own export rejects `z.date()`. Model tools send JSON, so a date is an\n// ISO string, and a union branch that is a `Date` object is dropped because\n// the model can only send its string branch.\nfunction toToolJsonSchema(\n\tschema: z.ZodType,\n\tmaxArrayItems: number | undefined\n): JsonSchema {\n\tconst { $schema: _, ...jsonSchema } = z.toJSONSchema(schema, {\n\t\tio: 'input',\n\t\ttarget: 'draft-7',\n\t\tunrepresentable: 'any',\n\t\toverride: ({ zodSchema, jsonSchema: node }) => {\n\t\t\tconst def = zodSchema._zod.def\n\n\t\t\tif (def.type === 'date') {\n\t\t\t\tnode.type = 'string'\n\t\t\t\tnode.format = 'date-time'\n\t\t\t}\n\n\t\t\tif (def.type === 'array' && maxArrayItems !== undefined) {\n\t\t\t\tconst ownMax =\n\t\t\t\t\ttypeof node.maxItems === 'number' ? node.maxItems : maxArrayItems\n\n\t\t\t\tnode.maxItems = Math.min(ownMax, maxArrayItems)\n\t\t\t}\n\n\t\t\tif (def.type === 'union') {\n\t\t\t\tconst isDateBranch = (index: number) =>\n\t\t\t\t\tdef.options[index]?._zod.def.type === 'date'\n\n\t\t\t\t// Zod writes a union as `anyOf`, or as `oneOf` when it is exclusive.\n\t\t\t\tfor (const keyword of ['anyOf', 'oneOf'] as const) {\n\t\t\t\t\tconst branches = node[keyword]\n\n\t\t\t\t\tif (Array.isArray(branches)) {\n\t\t\t\t\t\tnode[keyword] = branches.filter(\n\t\t\t\t\t\t\t(_branch, index) => !isDateBranch(index)\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t})\n\n\treturn jsonSchema\n}\n\nfunction withoutHiddenProperties(\n\tjsonSchema: JsonSchema,\n\thiddenInputs: readonly string[]\n): JsonSchema {\n\tconst { required, ...rest } = jsonSchema\n\tconst properties = { ...(jsonSchema.properties as JsonSchema | undefined) }\n\n\tfor (const name of hiddenInputs) {\n\t\tdelete properties[name]\n\t}\n\n\tconst visibleRequired = ((required as string[] | undefined) ?? []).filter(\n\t\t(name) => !hiddenInputs.includes(name)\n\t)\n\n\treturn {\n\t\t...rest,\n\t\tproperties,\n\t\t...(visibleRequired.length > 0 && { required: visibleRequired })\n\t}\n}\n\n/** A list longer than a write may hold, so every change fits one Undo request. */\nfunction findOverlongLists(\n\tvalue: unknown,\n\tmaxArrayItems: number | undefined,\n\tpath: readonly PropertyKey[]\n): readonly ValidationIssue[] {\n\tif (maxArrayItems === undefined) return []\n\n\tif (Array.isArray(value)) {\n\t\tconst own: readonly ValidationIssue[] =\n\t\t\tvalue.length > maxArrayItems\n\t\t\t\t? [{ message: `At most ${maxArrayItems} items in one change.`, path }]\n\t\t\t\t: []\n\n\t\treturn [\n\t\t\t...own,\n\t\t\t...value.flatMap((item, index) =>\n\t\t\t\tfindOverlongLists(item, maxArrayItems, [...path, index])\n\t\t\t)\n\t\t]\n\t}\n\n\tif (isPlainObject(value)) {\n\t\treturn Object.entries(value).flatMap(([key, item]) =>\n\t\t\tfindOverlongLists(item, maxArrayItems, [...path, key])\n\t\t)\n\t}\n\n\treturn []\n}\n\nfunction isHiddenInputIssue(\n\tissue: ValidationIssue,\n\thiddenInputs: readonly string[]\n): boolean {\n\tconst first = issue.path?.[0]\n\tconst key = typeof first === 'object' ? first.key : first\n\n\treturn typeof key === 'string' && hiddenInputs.includes(key)\n}\n\nfunction withoutKeys(value: unknown, keys: readonly string[]): unknown {\n\treturn isPlainObject(value)\n\t\t? Object.fromEntries(\n\t\t\t\tObject.entries(value).filter(([key]) => !keys.includes(key))\n\t\t\t)\n\t\t: value\n}\n\nfunction refusesOffsets(def: z.core.$ZodStringDef): boolean {\n\treturn (def.checks ?? []).some((check) => {\n\t\tconst checkDef = check._zod.def as {\n\t\t\treadonly format?: string\n\t\t\treadonly offset?: boolean\n\t\t}\n\n\t\treturn checkDef.format === 'datetime' && !checkDef.offset\n\t})\n}\n\nfunction toUtcDatetime(value: string): string {\n\tconst date = new Date(value)\n\tconst isNonUtcDatetime =\n\t\tNON_UTC_DATETIME.test(value) && !Number.isNaN(date.getTime())\n\n\treturn isNonUtcDatetime ? date.toISOString() : value\n}\n\nfunction isPlainObject(\n\tvalue: unknown\n): value is Readonly<Record<string, unknown>> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n"]}
1
+ {"version":3,"file":"toolInputSchema.js","sourceRoot":"","sources":["../../src/tools/toolInputSchema.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tool input schemas as Mastra takes them (a Standard Schema with JSON Schema\n * attached): a zod input described with every date as an ISO string, and any\n * schema with its hidden inputs removed. Validation checks the model's input\n * with the original schema but hands the raw input on, so a procedure parses\n * and transforms it once.\n */\n\nimport type { StandardSchemaWithJSON } from '@mastra/core/schema'\nimport { z } from 'zod'\n\ntype JsonSchema = Record<string, unknown>\n\ninterface ValidationIssue {\n\treadonly message: string\n\treadonly path?:\n\t\t| ReadonlyArray<PropertyKey | { readonly key: PropertyKey }>\n\t\t| undefined\n}\n\ntype ValidationResult =\n\t| { readonly value: unknown; readonly issues?: undefined }\n\t| { readonly issues: readonly ValidationIssue[]; readonly value?: undefined }\n\n/** A Standard Schema with JSON Schema attached, the form Mastra accepts as a tool input. */\nexport type ToolInputSchema = StandardSchemaWithJSON<unknown>\n\n/** An ISO datetime that ends in an offset such as `+02:00`, or in no zone at all, not `Z`. */\nconst NON_UTC_DATETIME = /^\\d{4}-\\d{2}-\\d{2}T[\\d:.]+(?:[+-]\\d{2}:?\\d{2})?$/\n\n/**\n * A zod object input as a tool input: `z.date()` offered as an ISO string and\n * coerced back before validation, and with `maxArrayItems` every list capped.\n * Throws for an input that is not an object, a programming error.\n */\nexport function toolInputSchema(\n\tschema: z.ZodType,\n\toptions: { readonly maxArrayItems?: number | undefined } = {}\n): ToolInputSchema {\n\tconst jsonSchema = toToolJsonSchema(schema, options.maxArrayItems)\n\n\tif (jsonSchema.type !== 'object') {\n\t\tthrow new Error('A tool must take an object input.')\n\t}\n\n\treturn standardSchema(jsonSchema, (value) => {\n\t\tconst input = coerceDateStrings(schema, value)\n\t\tconst result = schema['~standard'].validate(input) as\n\t\t\t| ValidationResult\n\t\t\t| Promise<ValidationResult>\n\n\t\tif (result instanceof Promise) {\n\t\t\tthrow new Error('A tool input must validate synchronously.')\n\t\t}\n\n\t\tconst issues = [\n\t\t\t...(result.issues ?? []),\n\t\t\t...findOverlongLists(input, options.maxArrayItems, [])\n\t\t]\n\n\t\treturn issues.length > 0 ? { issues } : { value: input }\n\t})\n}\n\n/**\n * The schema without the hidden inputs: the model neither sees nor sends\n * them. One the model sends is dropped, and an issue about one is left for\n * the tool, which receives the turn's value.\n */\nexport function withHiddenInputs(\n\tschema: ToolInputSchema,\n\thiddenInputs: readonly string[],\n\toptions: { readonly maxArrayItems?: number | undefined } = {}\n): ToolInputSchema {\n\tconst visible = (jsonSchema: JsonSchema) =>\n\t\twithoutHiddenProperties(jsonSchema, hiddenInputs)\n\n\tconst own = schema['~standard']\n\n\treturn {\n\t\t'~standard': {\n\t\t\tversion: 1,\n\t\t\tvendor: own.vendor,\n\t\t\tjsonSchema: {\n\t\t\t\tinput: (jsonOptions) => visible(own.jsonSchema.input(jsonOptions)),\n\t\t\t\toutput: (jsonOptions) => visible(own.jsonSchema.output(jsonOptions))\n\t\t\t},\n\t\t\tvalidate: (value) => {\n\t\t\t\tconst input = withoutKeys(value, hiddenInputs)\n\t\t\t\tconst finish = (result: ValidationResult): ValidationResult => {\n\t\t\t\t\tconst own = (result.issues ?? []).filter(\n\t\t\t\t\t\t(issue) => !isHiddenInputIssue(issue, hiddenInputs)\n\t\t\t\t\t)\n\t\t\t\t\t// A schema from `toolInputSchema` with the same cap already reported the list.\n\t\t\t\t\tconst issues = [\n\t\t\t\t\t\t...own,\n\t\t\t\t\t\t...findOverlongLists(input, options.maxArrayItems, []).filter(\n\t\t\t\t\t\t\t(issue) => !own.some((reported) => isSameIssue(reported, issue))\n\t\t\t\t\t\t)\n\t\t\t\t\t]\n\n\t\t\t\t\tif (issues.length > 0) return { issues }\n\n\t\t\t\t\treturn { value: result.issues ? input : result.value }\n\t\t\t\t}\n\t\t\t\tconst result = own.validate(input) as\n\t\t\t\t\t| ValidationResult\n\t\t\t\t\t| Promise<ValidationResult>\n\n\t\t\t\treturn (\n\t\t\t\t\tresult instanceof Promise ? result.then(finish) : finish(result)\n\t\t\t\t) as ReturnType<typeof own.validate>\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * The input with each ISO string a `z.date()` field takes turned into a\n * `Date`, and a datetime with an offset or no zone turned into UTC where\n * `z.string().datetime()` refuses offsets. A `Date` stays as it is, so an\n * approved call that comes back from the run's snapshot as JSON passes again.\n */\nexport function coerceDateStrings(\n\tschema: z.core.$ZodType,\n\tvalue: unknown\n): unknown {\n\tconst def = (schema as z.core.$ZodTypes)._zod.def\n\n\tswitch (def.type) {\n\t\tcase 'date':\n\t\t\treturn typeof value === 'string' && !def.coerce ? new Date(value) : value\n\t\tcase 'string':\n\t\t\treturn typeof value === 'string' && refusesOffsets(def)\n\t\t\t\t? toUtcDatetime(value)\n\t\t\t\t: value\n\t\tcase 'optional':\n\t\tcase 'nullable':\n\t\tcase 'default':\n\t\tcase 'prefault':\n\t\tcase 'readonly':\n\t\t\treturn value === undefined || value === null\n\t\t\t\t? value\n\t\t\t\t: coerceDateStrings(def.innerType, value)\n\t\tcase 'object':\n\t\t\treturn isPlainObject(value)\n\t\t\t\t? Object.fromEntries(\n\t\t\t\t\t\tObject.entries(value).map(([key, field]) => {\n\t\t\t\t\t\t\tconst fieldSchema = def.shape[key]\n\n\t\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\t\tfieldSchema ? coerceDateStrings(fieldSchema, field) : field\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t: value\n\t\tcase 'array':\n\t\t\treturn Array.isArray(value)\n\t\t\t\t? value.map((item) => coerceDateStrings(def.element, item))\n\t\t\t\t: value\n\t\tdefault:\n\t\t\treturn value\n\t}\n}\n\nfunction standardSchema(\n\tjsonSchema: JsonSchema,\n\tvalidate: (value: unknown) => ValidationResult\n): ToolInputSchema {\n\treturn {\n\t\t'~standard': {\n\t\t\tversion: 1,\n\t\t\tvendor: 'better-mastra',\n\t\t\tvalidate: validate as ToolInputSchema['~standard']['validate'],\n\t\t\tjsonSchema: { input: () => jsonSchema, output: () => jsonSchema }\n\t\t}\n\t}\n}\n\n// Zod's own export rejects `z.date()`. Model tools send JSON, so a date is an\n// ISO string, and a union branch that is a `Date` object is dropped because\n// the model can only send its string branch.\nfunction toToolJsonSchema(\n\tschema: z.ZodType,\n\tmaxArrayItems: number | undefined\n): JsonSchema {\n\tconst { $schema: _, ...jsonSchema } = z.toJSONSchema(schema, {\n\t\tio: 'input',\n\t\ttarget: 'draft-7',\n\t\tunrepresentable: 'any',\n\t\toverride: ({ zodSchema, jsonSchema: node }) => {\n\t\t\tconst def = zodSchema._zod.def\n\n\t\t\tif (def.type === 'date') {\n\t\t\t\tnode.type = 'string'\n\t\t\t\tnode.format = 'date-time'\n\t\t\t}\n\n\t\t\tif (def.type === 'array' && maxArrayItems !== undefined) {\n\t\t\t\tconst ownMax =\n\t\t\t\t\ttypeof node.maxItems === 'number' ? node.maxItems : maxArrayItems\n\n\t\t\t\tnode.maxItems = Math.min(ownMax, maxArrayItems)\n\t\t\t}\n\n\t\t\tif (def.type === 'union') {\n\t\t\t\tconst isDateBranch = (index: number) =>\n\t\t\t\t\tdef.options[index]?._zod.def.type === 'date'\n\n\t\t\t\t// Zod writes a union as `anyOf`, or as `oneOf` when it is exclusive.\n\t\t\t\tfor (const keyword of ['anyOf', 'oneOf'] as const) {\n\t\t\t\t\tconst branches = node[keyword]\n\n\t\t\t\t\tif (Array.isArray(branches)) {\n\t\t\t\t\t\tnode[keyword] = branches.filter(\n\t\t\t\t\t\t\t(_branch, index) => !isDateBranch(index)\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t})\n\n\treturn jsonSchema\n}\n\nfunction withoutHiddenProperties(\n\tjsonSchema: JsonSchema,\n\thiddenInputs: readonly string[]\n): JsonSchema {\n\tconst { required, ...rest } = jsonSchema\n\tconst properties = { ...(jsonSchema.properties as JsonSchema | undefined) }\n\n\tfor (const name of hiddenInputs) {\n\t\tdelete properties[name]\n\t}\n\n\tconst visibleRequired = ((required as string[] | undefined) ?? []).filter(\n\t\t(name) => !hiddenInputs.includes(name)\n\t)\n\n\treturn {\n\t\t...rest,\n\t\tproperties,\n\t\t...(visibleRequired.length > 0 && { required: visibleRequired })\n\t}\n}\n\n/** A list longer than a write may hold, so every change fits one Undo request. */\nfunction findOverlongLists(\n\tvalue: unknown,\n\tmaxArrayItems: number | undefined,\n\tpath: readonly PropertyKey[]\n): readonly ValidationIssue[] {\n\tif (maxArrayItems === undefined) return []\n\n\tif (Array.isArray(value)) {\n\t\tconst own: readonly ValidationIssue[] =\n\t\t\tvalue.length > maxArrayItems\n\t\t\t\t? [{ message: `At most ${maxArrayItems} items in one change.`, path }]\n\t\t\t\t: []\n\n\t\treturn [\n\t\t\t...own,\n\t\t\t...value.flatMap((item, index) =>\n\t\t\t\tfindOverlongLists(item, maxArrayItems, [...path, index])\n\t\t\t)\n\t\t]\n\t}\n\n\tif (isPlainObject(value)) {\n\t\treturn Object.entries(value).flatMap(([key, item]) =>\n\t\t\tfindOverlongLists(item, maxArrayItems, [...path, key])\n\t\t)\n\t}\n\n\treturn []\n}\n\nfunction isHiddenInputIssue(\n\tissue: ValidationIssue,\n\thiddenInputs: readonly string[]\n): boolean {\n\tconst first = issue.path?.[0]\n\tconst key = typeof first === 'object' ? first.key : first\n\n\treturn typeof key === 'string' && hiddenInputs.includes(key)\n}\n\nfunction withoutKeys(value: unknown, keys: readonly string[]): unknown {\n\treturn isPlainObject(value)\n\t\t? Object.fromEntries(\n\t\t\t\tObject.entries(value).filter(([key]) => !keys.includes(key))\n\t\t\t)\n\t\t: value\n}\n\nfunction refusesOffsets(def: z.core.$ZodStringDef): boolean {\n\treturn (def.checks ?? []).some((check) => {\n\t\tconst checkDef = check._zod.def as {\n\t\t\treadonly format?: string\n\t\t\treadonly offset?: boolean\n\t\t}\n\n\t\treturn checkDef.format === 'datetime' && !checkDef.offset\n\t})\n}\n\nfunction toUtcDatetime(value: string): string {\n\tconst date = new Date(value)\n\tconst isNonUtcDatetime =\n\t\tNON_UTC_DATETIME.test(value) && !Number.isNaN(date.getTime())\n\n\treturn isNonUtcDatetime ? date.toISOString() : value\n}\n\nfunction isPlainObject(\n\tvalue: unknown\n): value is Readonly<Record<string, unknown>> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction isSameIssue(\n\tleft: { readonly message: string; readonly path?: unknown },\n\tright: { readonly message: string; readonly path?: unknown }\n): boolean {\n\treturn (\n\t\tleft.message === right.message &&\n\t\tJSON.stringify(left.path ?? []) === JSON.stringify(right.path ?? [])\n\t)\n}\n"]}
@@ -4,12 +4,12 @@ export { chatErrorResponse, chatRefusal } from './errors.js';
4
4
  export { createTurnObserver, type ToolSettledEvent, type TurnObserver, type TurnOutcome, type TurnSummary } from './observer.js';
5
5
  export { LAST_STEP_SIGNAL, RetryBeforeAnswerText, TOOL_CALL_BUDGET_STOP_REASON, ToolCallBudgetStop, TurnSignals } from './processors.js';
6
6
  export { CACHE_MARKER, markConversationForCache, withCacheControl, withConversationCache } from './promptCache.js';
7
- export { createReplySuggestionsAgent, REPLY_SUGGESTIONS_PART, replySuggestionsSchema, sendReplySuggestions, toReplySuggestions } from './replySuggestions.js';
7
+ export { createReplySuggestionsAgent, REPLY_SUGGESTIONS_PART, replySuggestionsSchema, sendReplySuggestions, toReplySuggestions, toReplySuggestionsMessage } from './replySuggestions.js';
8
8
  export { type DefinedRequestContext, defineRequestContext, defineRequestContextHolder, type RequestContextHolder } from './requestContext.js';
9
9
  export { SSE_HEARTBEAT_MS, toChatStreamResponse } from './response.js';
10
- export { type ChatTurnDeps, type ChatTurnLogger, type ChatTurnRequest, type ChatTurnResult, type ChatTurnSinks, type ChatTurnStage, clientToolErrorsAsResults, type PreparedChatTurn, refused, runChatTurn, type TurnFinishedEvent, type TurnLabels, type TurnUsageEvent } from './runChatTurn.js';
10
+ export { type ChatTurnDeps, type ChatTurnLogger, type ChatTurnRequest, type ChatTurnResult, type ChatTurnSinks, type ChatTurnStage, type PreparedChatTurn, refused, runChatTurn, type TurnFinishedEvent, type TurnLabels, type TurnUsageEvent } from './runChatTurn.js';
11
11
  export { isUserFacingPart, TURN_ERROR_SENTENCE, type TurnStreamEnding, toUserFacingMessage, toUserFacingStream, USER_MESSAGE_PART, type UserFacingStreamHandlers } from './stream.js';
12
- export { type AnswerRating, type AnswerRatingStore, createThreadHandlers, type DeleteThreadResult, deleteThreadEverywhere, sweepAbandonedRuns, sweepOldThreads, type ThreadHandlersOptions, type ThreadPage, type ThreadSummary } from './threads.js';
12
+ export { type AnswerRating, type AnswerRatingStore, createThreadHandlers, type DeleteThreadResult, deleteThreadEverywhere, sweepAbandonedRuns, type AbandonedRun, sweepOldThreads, type ThreadHandlersOptions, type ThreadPage, type ThreadSummary } from './threads.js';
13
13
  export { defineModelArms, type ModelArms, threadBucket } from './modelArms.js';
14
14
  export { measurePromptBudget, measureToolSchemas, type PromptBudget } from './promptBudget.js';
15
15
  export { type PromptVersionTool, promptVersion } from './promptVersion.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/turn/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,YAAY,EACZ,KAAK,sBAAsB,EAC3B,eAAe,EACf,MAAM,YAAY,CAAA;AACnB,OAAO,EACN,qBAAqB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,wBAAwB,EACxB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,EACN,kBAAkB,EAClB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,MAAM,eAAe,CAAA;AACtB,OAAO,EACN,gBAAgB,EAChB,qBAAqB,EACrB,4BAA4B,EAC5B,kBAAkB,EAClB,WAAW,EACX,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACN,YAAY,EACZ,wBAAwB,EACxB,gBAAgB,EAChB,qBAAqB,EACrB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACN,2BAA2B,EAC3B,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACN,KAAK,qBAAqB,EAC1B,oBAAoB,EACpB,0BAA0B,EAC1B,KAAK,oBAAoB,EACzB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACtE,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,yBAAyB,EACzB,KAAK,gBAAgB,EACrB,OAAO,EACP,WAAW,EACX,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACN,gBAAgB,EAChB,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,MAAM,aAAa,CAAA;AACpB,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,oBAAoB,EACpB,KAAK,kBAAkB,EACvB,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EACf,KAAK,qBAAqB,EAC1B,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC9E,OAAO,EACN,mBAAmB,EACnB,kBAAkB,EAClB,KAAK,YAAY,EACjB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,KAAK,iBAAiB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAC1E,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AACrE,OAAO,EACN,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,cAAc,EACd,YAAY,EACZ,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,gBAAgB,EAChB,KAAK,SAAS,EACd,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/turn/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,YAAY,EACZ,KAAK,sBAAsB,EAC3B,eAAe,EACf,MAAM,YAAY,CAAA;AACnB,OAAO,EACN,qBAAqB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,wBAAwB,EACxB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,EACN,kBAAkB,EAClB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,MAAM,eAAe,CAAA;AACtB,OAAO,EACN,gBAAgB,EAChB,qBAAqB,EACrB,4BAA4B,EAC5B,kBAAkB,EAClB,WAAW,EACX,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACN,YAAY,EACZ,wBAAwB,EACxB,gBAAgB,EAChB,qBAAqB,EACrB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACN,2BAA2B,EAC3B,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,yBAAyB,EACzB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACN,KAAK,qBAAqB,EAC1B,oBAAoB,EACpB,0BAA0B,EAC1B,KAAK,oBAAoB,EACzB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACtE,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,OAAO,EACP,WAAW,EACX,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACN,gBAAgB,EAChB,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,MAAM,aAAa,CAAA;AACpB,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,oBAAoB,EACpB,KAAK,kBAAkB,EACvB,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,YAAY,EACjB,eAAe,EACf,KAAK,qBAAqB,EAC1B,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC9E,OAAO,EACN,mBAAmB,EACnB,kBAAkB,EAClB,KAAK,YAAY,EACjB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,KAAK,iBAAiB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAC1E,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AACrE,OAAO,EACN,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,cAAc,EACd,YAAY,EACZ,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,gBAAgB,EAChB,KAAK,SAAS,EACd,MAAM,YAAY,CAAA"}
@@ -4,10 +4,10 @@ export { chatErrorResponse, chatRefusal } from './errors.js';
4
4
  export { createTurnObserver } from './observer.js';
5
5
  export { LAST_STEP_SIGNAL, RetryBeforeAnswerText, TOOL_CALL_BUDGET_STOP_REASON, ToolCallBudgetStop, TurnSignals } from './processors.js';
6
6
  export { CACHE_MARKER, markConversationForCache, withCacheControl, withConversationCache } from './promptCache.js';
7
- export { createReplySuggestionsAgent, REPLY_SUGGESTIONS_PART, replySuggestionsSchema, sendReplySuggestions, toReplySuggestions } from './replySuggestions.js';
7
+ export { createReplySuggestionsAgent, REPLY_SUGGESTIONS_PART, replySuggestionsSchema, sendReplySuggestions, toReplySuggestions, toReplySuggestionsMessage } from './replySuggestions.js';
8
8
  export { defineRequestContext, defineRequestContextHolder } from './requestContext.js';
9
9
  export { SSE_HEARTBEAT_MS, toChatStreamResponse } from './response.js';
10
- export { clientToolErrorsAsResults, refused, runChatTurn } from './runChatTurn.js';
10
+ export { refused, runChatTurn } from './runChatTurn.js';
11
11
  export { isUserFacingPart, TURN_ERROR_SENTENCE, toUserFacingMessage, toUserFacingStream, USER_MESSAGE_PART } from './stream.js';
12
12
  export { createThreadHandlers, deleteThreadEverywhere, sweepAbandonedRuns, sweepOldThreads } from './threads.js';
13
13
  export { defineModelArms, threadBucket } from './modelArms.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/turn/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,YAAY,EAEZ,eAAe,EACf,MAAM,YAAY,CAAA;AACnB,OAAO,EACN,qBAAqB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,wBAAwB,EAGxB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,EACN,kBAAkB,EAKlB,MAAM,eAAe,CAAA;AACtB,OAAO,EACN,gBAAgB,EAChB,qBAAqB,EACrB,4BAA4B,EAC5B,kBAAkB,EAClB,WAAW,EACX,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACN,YAAY,EACZ,wBAAwB,EACxB,gBAAgB,EAChB,qBAAqB,EACrB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACN,2BAA2B,EAC3B,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAEN,oBAAoB,EACpB,0BAA0B,EAE1B,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACtE,OAAO,EAON,yBAAyB,EAEzB,OAAO,EACP,WAAW,EAIX,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACN,gBAAgB,EAChB,mBAAmB,EAEnB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EAEjB,MAAM,aAAa,CAAA;AACpB,OAAO,EAGN,oBAAoB,EAEpB,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EAIf,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,eAAe,EAAkB,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC9E,OAAO,EACN,mBAAmB,EACnB,kBAAkB,EAElB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAA0B,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAC1E,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AACrE,OAAO,EAON,cAAc,EACd,YAAY,EAGZ,gBAAgB,EAEhB,MAAM,YAAY,CAAA","sourcesContent":["export {\n\tasAgentModel,\n\ttype CreateChatAgentOptions,\n\tcreateChatAgent\n} from './agent.js'\nexport {\n\tAPPROVAL_ID_SEPARATOR,\n\tclassifyTurnChanges,\n\tlistPendingChanges,\n\tMOVED_ON_REASON,\n\tmoveOnFromWaitingChanges,\n\ttype PendingChange,\n\ttype TurnChanges\n} from './changes.js'\nexport { chatErrorResponse, chatRefusal } from './errors.js'\nexport {\n\tcreateTurnObserver,\n\ttype ToolSettledEvent,\n\ttype TurnObserver,\n\ttype TurnOutcome,\n\ttype TurnSummary\n} from './observer.js'\nexport {\n\tLAST_STEP_SIGNAL,\n\tRetryBeforeAnswerText,\n\tTOOL_CALL_BUDGET_STOP_REASON,\n\tToolCallBudgetStop,\n\tTurnSignals\n} from './processors.js'\nexport {\n\tCACHE_MARKER,\n\tmarkConversationForCache,\n\twithCacheControl,\n\twithConversationCache\n} from './promptCache.js'\nexport {\n\tcreateReplySuggestionsAgent,\n\tREPLY_SUGGESTIONS_PART,\n\treplySuggestionsSchema,\n\tsendReplySuggestions,\n\ttoReplySuggestions\n} from './replySuggestions.js'\nexport {\n\ttype DefinedRequestContext,\n\tdefineRequestContext,\n\tdefineRequestContextHolder,\n\ttype RequestContextHolder\n} from './requestContext.js'\nexport { SSE_HEARTBEAT_MS, toChatStreamResponse } from './response.js'\nexport {\n\ttype ChatTurnDeps,\n\ttype ChatTurnLogger,\n\ttype ChatTurnRequest,\n\ttype ChatTurnResult,\n\ttype ChatTurnSinks,\n\ttype ChatTurnStage,\n\tclientToolErrorsAsResults,\n\ttype PreparedChatTurn,\n\trefused,\n\trunChatTurn,\n\ttype TurnFinishedEvent,\n\ttype TurnLabels,\n\ttype TurnUsageEvent\n} from './runChatTurn.js'\nexport {\n\tisUserFacingPart,\n\tTURN_ERROR_SENTENCE,\n\ttype TurnStreamEnding,\n\ttoUserFacingMessage,\n\ttoUserFacingStream,\n\tUSER_MESSAGE_PART,\n\ttype UserFacingStreamHandlers\n} from './stream.js'\nexport {\n\ttype AnswerRating,\n\ttype AnswerRatingStore,\n\tcreateThreadHandlers,\n\ttype DeleteThreadResult,\n\tdeleteThreadEverywhere,\n\tsweepAbandonedRuns,\n\tsweepOldThreads,\n\ttype ThreadHandlersOptions,\n\ttype ThreadPage,\n\ttype ThreadSummary\n} from './threads.js'\nexport { defineModelArms, type ModelArms, threadBucket } from './modelArms.js'\nexport {\n\tmeasurePromptBudget,\n\tmeasureToolSchemas,\n\ttype PromptBudget\n} from './promptBudget.js'\nexport { type PromptVersionTool, promptVersion } from './promptVersion.js'\nexport { deriveThreadTitle, persistThreadMetadata } from './title.js'\nexport {\n\ttype AnyRequestContext,\n\ttype ChatErrorCode,\n\ttype ChatRefusal,\n\ttype ChatResume,\n\ttype ChatTurnBody,\n\ttype ChatTurnPlan,\n\tchatErrorCodes,\n\tfindTurnPlan,\n\ttype LanguageModelObject,\n\ttype ProviderOptions,\n\trememberTurnPlan,\n\ttype ThreadKey\n} from './types.js'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/turn/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,YAAY,EAEZ,eAAe,EACf,MAAM,YAAY,CAAA;AACnB,OAAO,EACN,qBAAqB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,wBAAwB,EAGxB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,EACN,kBAAkB,EAKlB,MAAM,eAAe,CAAA;AACtB,OAAO,EACN,gBAAgB,EAChB,qBAAqB,EACrB,4BAA4B,EAC5B,kBAAkB,EAClB,WAAW,EACX,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACN,YAAY,EACZ,wBAAwB,EACxB,gBAAgB,EAChB,qBAAqB,EACrB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACN,2BAA2B,EAC3B,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,yBAAyB,EACzB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAEN,oBAAoB,EACpB,0BAA0B,EAE1B,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACtE,OAAO,EAQN,OAAO,EACP,WAAW,EAIX,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACN,gBAAgB,EAChB,mBAAmB,EAEnB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EAEjB,MAAM,aAAa,CAAA;AACpB,OAAO,EAGN,oBAAoB,EAEpB,sBAAsB,EACtB,kBAAkB,EAElB,eAAe,EAIf,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,eAAe,EAAkB,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC9E,OAAO,EACN,mBAAmB,EACnB,kBAAkB,EAElB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAA0B,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAC1E,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AACrE,OAAO,EAON,cAAc,EACd,YAAY,EAGZ,gBAAgB,EAEhB,MAAM,YAAY,CAAA","sourcesContent":["export {\n\tasAgentModel,\n\ttype CreateChatAgentOptions,\n\tcreateChatAgent\n} from './agent.js'\nexport {\n\tAPPROVAL_ID_SEPARATOR,\n\tclassifyTurnChanges,\n\tlistPendingChanges,\n\tMOVED_ON_REASON,\n\tmoveOnFromWaitingChanges,\n\ttype PendingChange,\n\ttype TurnChanges\n} from './changes.js'\nexport { chatErrorResponse, chatRefusal } from './errors.js'\nexport {\n\tcreateTurnObserver,\n\ttype ToolSettledEvent,\n\ttype TurnObserver,\n\ttype TurnOutcome,\n\ttype TurnSummary\n} from './observer.js'\nexport {\n\tLAST_STEP_SIGNAL,\n\tRetryBeforeAnswerText,\n\tTOOL_CALL_BUDGET_STOP_REASON,\n\tToolCallBudgetStop,\n\tTurnSignals\n} from './processors.js'\nexport {\n\tCACHE_MARKER,\n\tmarkConversationForCache,\n\twithCacheControl,\n\twithConversationCache\n} from './promptCache.js'\nexport {\n\tcreateReplySuggestionsAgent,\n\tREPLY_SUGGESTIONS_PART,\n\treplySuggestionsSchema,\n\tsendReplySuggestions,\n\ttoReplySuggestions,\n\ttoReplySuggestionsMessage\n} from './replySuggestions.js'\nexport {\n\ttype DefinedRequestContext,\n\tdefineRequestContext,\n\tdefineRequestContextHolder,\n\ttype RequestContextHolder\n} from './requestContext.js'\nexport { SSE_HEARTBEAT_MS, toChatStreamResponse } from './response.js'\nexport {\n\ttype ChatTurnDeps,\n\ttype ChatTurnLogger,\n\ttype ChatTurnRequest,\n\ttype ChatTurnResult,\n\ttype ChatTurnSinks,\n\ttype ChatTurnStage,\n\ttype PreparedChatTurn,\n\trefused,\n\trunChatTurn,\n\ttype TurnFinishedEvent,\n\ttype TurnLabels,\n\ttype TurnUsageEvent\n} from './runChatTurn.js'\nexport {\n\tisUserFacingPart,\n\tTURN_ERROR_SENTENCE,\n\ttype TurnStreamEnding,\n\ttoUserFacingMessage,\n\ttoUserFacingStream,\n\tUSER_MESSAGE_PART,\n\ttype UserFacingStreamHandlers\n} from './stream.js'\nexport {\n\ttype AnswerRating,\n\ttype AnswerRatingStore,\n\tcreateThreadHandlers,\n\ttype DeleteThreadResult,\n\tdeleteThreadEverywhere,\n\tsweepAbandonedRuns,\n\ttype AbandonedRun,\n\tsweepOldThreads,\n\ttype ThreadHandlersOptions,\n\ttype ThreadPage,\n\ttype ThreadSummary\n} from './threads.js'\nexport { defineModelArms, type ModelArms, threadBucket } from './modelArms.js'\nexport {\n\tmeasurePromptBudget,\n\tmeasureToolSchemas,\n\ttype PromptBudget\n} from './promptBudget.js'\nexport { type PromptVersionTool, promptVersion } from './promptVersion.js'\nexport { deriveThreadTitle, persistThreadMetadata } from './title.js'\nexport {\n\ttype AnyRequestContext,\n\ttype ChatErrorCode,\n\ttype ChatRefusal,\n\ttype ChatResume,\n\ttype ChatTurnBody,\n\ttype ChatTurnPlan,\n\tchatErrorCodes,\n\tfindTurnPlan,\n\ttype LanguageModelObject,\n\ttype ProviderOptions,\n\trememberTurnPlan,\n\ttype ThreadKey\n} from './types.js'\n"]}
@@ -26,6 +26,8 @@ export declare const replySuggestionsSchema: z.ZodObject<{
26
26
  */
27
27
  export declare function createReplySuggestionsAgent(input: {
28
28
  readonly id: string;
29
+ /** The agent's name in Studio and traces. Default the id. */
30
+ readonly name?: string;
29
31
  readonly instructions: string;
30
32
  readonly model: () => LanguageModel;
31
33
  }): Agent;