agentfootprint 10.2.0 → 10.3.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.
- package/CAPABILITIES.md +1 -0
- package/dist/adapters/llm/AnthropicProvider.js +11 -2
- package/dist/adapters/llm/AnthropicProvider.js.map +1 -1
- package/dist/adapters/llm/BrowserAnthropicProvider.js +11 -2
- package/dist/adapters/llm/BrowserAnthropicProvider.js.map +1 -1
- package/dist/adapters/llm/MockProvider.js +11 -1
- package/dist/adapters/llm/MockProvider.js.map +1 -1
- package/dist/adapters/llm/anthropicMessagesWire.js +19 -0
- package/dist/adapters/llm/anthropicMessagesWire.js.map +1 -1
- package/dist/adapters/llm/anthropicModels.js +48 -14
- package/dist/adapters/llm/anthropicModels.js.map +1 -1
- package/dist/adapters/llm/wireManifest.js +8 -2
- package/dist/adapters/llm/wireManifest.js.map +1 -1
- package/dist/adapters/nativeOutputSchema.js +80 -0
- package/dist/adapters/nativeOutputSchema.js.map +1 -0
- package/dist/adapters/requestRefusal.js +2 -0
- package/dist/adapters/requestRefusal.js.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/core/Agent.js +74 -22
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/agent/AgentBuilder.js +23 -0
- package/dist/core/agent/AgentBuilder.js.map +1 -1
- package/dist/core/agent/buildDynamicAgentChart.js +5 -0
- package/dist/core/agent/buildDynamicAgentChart.js.map +1 -1
- package/dist/core/agent/findings/reserved.js +50 -1
- package/dist/core/agent/findings/reserved.js.map +1 -1
- package/dist/core/agent/nativeOutputFormat.js +389 -0
- package/dist/core/agent/nativeOutputFormat.js.map +1 -0
- package/dist/core/agent/outputEnforcement.js +35 -1
- package/dist/core/agent/outputEnforcement.js.map +1 -1
- package/dist/core/agent/stages/answerValidation.js +14 -4
- package/dist/core/agent/stages/answerValidation.js.map +1 -1
- package/dist/core/agent/stages/callLLM.js +24 -0
- package/dist/core/agent/stages/callLLM.js.map +1 -1
- package/dist/core/agent/stages/outputRetry.js +1 -0
- package/dist/core/agent/stages/outputRetry.js.map +1 -1
- package/dist/core/agent/stages/route.js +33 -10
- package/dist/core/agent/stages/route.js.map +1 -1
- package/dist/core/outputSchema.js.map +1 -1
- package/dist/esm/adapters/llm/AnthropicProvider.d.ts +3 -0
- package/dist/esm/adapters/llm/AnthropicProvider.js +12 -3
- package/dist/esm/adapters/llm/AnthropicProvider.js.map +1 -1
- package/dist/esm/adapters/llm/BrowserAnthropicProvider.d.ts +3 -0
- package/dist/esm/adapters/llm/BrowserAnthropicProvider.js +12 -3
- package/dist/esm/adapters/llm/BrowserAnthropicProvider.js.map +1 -1
- package/dist/esm/adapters/llm/MockProvider.d.ts +7 -0
- package/dist/esm/adapters/llm/MockProvider.js +11 -1
- package/dist/esm/adapters/llm/MockProvider.js.map +1 -1
- package/dist/esm/adapters/llm/anthropicMessagesWire.d.ts +13 -0
- package/dist/esm/adapters/llm/anthropicMessagesWire.js +19 -0
- package/dist/esm/adapters/llm/anthropicMessagesWire.js.map +1 -1
- package/dist/esm/adapters/llm/anthropicModels.d.ts +36 -3
- package/dist/esm/adapters/llm/anthropicModels.js +46 -13
- package/dist/esm/adapters/llm/anthropicModels.js.map +1 -1
- package/dist/esm/adapters/llm/wireManifest.d.ts +9 -1
- package/dist/esm/adapters/llm/wireManifest.js +8 -2
- package/dist/esm/adapters/llm/wireManifest.js.map +1 -1
- package/dist/esm/adapters/nativeOutputSchema.d.ts +66 -0
- package/dist/esm/adapters/nativeOutputSchema.js +75 -0
- package/dist/esm/adapters/nativeOutputSchema.js.map +1 -0
- package/dist/esm/adapters/requestRefusal.js +2 -0
- package/dist/esm/adapters/requestRefusal.js.map +1 -1
- package/dist/esm/adapters/types.d.ts +40 -0
- package/dist/esm/adapters/types.js.map +1 -1
- package/dist/esm/core/Agent.d.ts +16 -0
- package/dist/esm/core/Agent.js +74 -22
- package/dist/esm/core/Agent.js.map +1 -1
- package/dist/esm/core/agent/AgentBuilder.js +23 -0
- package/dist/esm/core/agent/AgentBuilder.js.map +1 -1
- package/dist/esm/core/agent/buildDynamicAgentChart.js +5 -0
- package/dist/esm/core/agent/buildDynamicAgentChart.js.map +1 -1
- package/dist/esm/core/agent/findings/reserved.d.ts +16 -0
- package/dist/esm/core/agent/findings/reserved.js +48 -0
- package/dist/esm/core/agent/findings/reserved.js.map +1 -1
- package/dist/esm/core/agent/nativeOutputFormat.d.ts +85 -0
- package/dist/esm/core/agent/nativeOutputFormat.js +384 -0
- package/dist/esm/core/agent/nativeOutputFormat.js.map +1 -0
- package/dist/esm/core/agent/outputEnforcement.d.ts +33 -1
- package/dist/esm/core/agent/outputEnforcement.js +33 -0
- package/dist/esm/core/agent/outputEnforcement.js.map +1 -1
- package/dist/esm/core/agent/stages/answerValidation.d.ts +1 -1
- package/dist/esm/core/agent/stages/answerValidation.js +14 -4
- package/dist/esm/core/agent/stages/answerValidation.js.map +1 -1
- package/dist/esm/core/agent/stages/callLLM.d.ts +9 -1
- package/dist/esm/core/agent/stages/callLLM.js +24 -0
- package/dist/esm/core/agent/stages/callLLM.js.map +1 -1
- package/dist/esm/core/agent/stages/outputRetry.js +1 -0
- package/dist/esm/core/agent/stages/outputRetry.js.map +1 -1
- package/dist/esm/core/agent/stages/route.js +34 -11
- package/dist/esm/core/agent/stages/route.js.map +1 -1
- package/dist/esm/core/agent/types.d.ts +19 -3
- package/dist/esm/core/outputSchema.d.ts +30 -3
- package/dist/esm/core/outputSchema.js.map +1 -1
- package/dist/esm/lib/time-travel/receipt.d.ts +11 -0
- package/dist/esm/lib/time-travel/receipt.js +8 -2
- package/dist/esm/lib/time-travel/receipt.js.map +1 -1
- package/dist/esm/providers.d.ts +1 -0
- package/dist/esm/providers.js +1 -0
- package/dist/esm/providers.js.map +1 -1
- package/dist/esm/resilience/withCircuitBreaker.js +7 -0
- package/dist/esm/resilience/withCircuitBreaker.js.map +1 -1
- package/dist/esm/resilience/withFallback.js +10 -0
- package/dist/esm/resilience/withFallback.js.map +1 -1
- package/dist/esm/resilience/withRetry.js +8 -0
- package/dist/esm/resilience/withRetry.js.map +1 -1
- package/dist/lib/time-travel/receipt.js +8 -2
- package/dist/lib/time-travel/receipt.js.map +1 -1
- package/dist/providers.js +4 -1
- package/dist/providers.js.map +1 -1
- package/dist/resilience/withCircuitBreaker.js +7 -0
- package/dist/resilience/withCircuitBreaker.js.map +1 -1
- package/dist/resilience/withFallback.js +10 -0
- package/dist/resilience/withFallback.js.map +1 -1
- package/dist/resilience/withRetry.js +8 -0
- package/dist/resilience/withRetry.js.map +1 -1
- package/dist/types/adapters/llm/AnthropicProvider.d.ts +3 -0
- package/dist/types/adapters/llm/AnthropicProvider.d.ts.map +1 -1
- package/dist/types/adapters/llm/BrowserAnthropicProvider.d.ts +3 -0
- package/dist/types/adapters/llm/BrowserAnthropicProvider.d.ts.map +1 -1
- package/dist/types/adapters/llm/MockProvider.d.ts +7 -0
- package/dist/types/adapters/llm/MockProvider.d.ts.map +1 -1
- package/dist/types/adapters/llm/anthropicMessagesWire.d.ts +13 -0
- package/dist/types/adapters/llm/anthropicMessagesWire.d.ts.map +1 -1
- package/dist/types/adapters/llm/anthropicModels.d.ts +36 -3
- package/dist/types/adapters/llm/anthropicModels.d.ts.map +1 -1
- package/dist/types/adapters/llm/wireManifest.d.ts +9 -1
- package/dist/types/adapters/llm/wireManifest.d.ts.map +1 -1
- package/dist/types/adapters/nativeOutputSchema.d.ts +67 -0
- package/dist/types/adapters/nativeOutputSchema.d.ts.map +1 -0
- package/dist/types/adapters/requestRefusal.d.ts.map +1 -1
- package/dist/types/adapters/types.d.ts +40 -0
- package/dist/types/adapters/types.d.ts.map +1 -1
- package/dist/types/core/Agent.d.ts +16 -0
- package/dist/types/core/Agent.d.ts.map +1 -1
- package/dist/types/core/agent/AgentBuilder.d.ts.map +1 -1
- package/dist/types/core/agent/buildDynamicAgentChart.d.ts.map +1 -1
- package/dist/types/core/agent/findings/reserved.d.ts +16 -0
- package/dist/types/core/agent/findings/reserved.d.ts.map +1 -1
- package/dist/types/core/agent/nativeOutputFormat.d.ts +86 -0
- package/dist/types/core/agent/nativeOutputFormat.d.ts.map +1 -0
- package/dist/types/core/agent/outputEnforcement.d.ts +33 -1
- package/dist/types/core/agent/outputEnforcement.d.ts.map +1 -1
- package/dist/types/core/agent/stages/answerValidation.d.ts +1 -1
- package/dist/types/core/agent/stages/answerValidation.d.ts.map +1 -1
- package/dist/types/core/agent/stages/callLLM.d.ts +9 -1
- package/dist/types/core/agent/stages/callLLM.d.ts.map +1 -1
- package/dist/types/core/agent/stages/outputRetry.d.ts.map +1 -1
- package/dist/types/core/agent/stages/route.d.ts.map +1 -1
- package/dist/types/core/agent/types.d.ts +19 -3
- package/dist/types/core/agent/types.d.ts.map +1 -1
- package/dist/types/core/outputSchema.d.ts +30 -3
- package/dist/types/core/outputSchema.d.ts.map +1 -1
- package/dist/types/lib/time-travel/receipt.d.ts +11 -0
- package/dist/types/lib/time-travel/receipt.d.ts.map +1 -1
- package/dist/types/providers.d.ts +1 -0
- package/dist/types/providers.d.ts.map +1 -1
- package/dist/types/resilience/withCircuitBreaker.d.ts.map +1 -1
- package/dist/types/resilience/withFallback.d.ts.map +1 -1
- package/dist/types/resilience/withRetry.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* nativeOutputFormat — the ONE builder of the JSON Schema that
|
|
4
|
+
* `.outputSchema(parser, { strategy: 'native' })` sends as the provider's
|
|
5
|
+
* structured-output format (Anthropic's `output_config.format`).
|
|
6
|
+
*
|
|
7
|
+
* Pattern: pure transform over plain JSON, run once at build
|
|
8
|
+
* (`AgentBuilder · resolveOutputEnforcement`); no scope, no I/O.
|
|
9
|
+
* Role: core/ agent leaf. Its input is the SAME schema the `'tool-forced'`
|
|
10
|
+
* strategy puts on its synthetic tool (`outputEnforcement.ts ·
|
|
11
|
+
* resolveJsonSchema`: the `jsonSchema` option, else the parser's own
|
|
12
|
+
* `toJsonSchema()`), and the SAME parser judges every answer after —
|
|
13
|
+
* so the wire copy may be looser than the contract, never different
|
|
14
|
+
* from it.
|
|
15
|
+
*
|
|
16
|
+
* THE RULES, from Anthropic's structured-outputs page ("JSON Schema
|
|
17
|
+
* limitations", fetched 2026-10-14 —
|
|
18
|
+
* https://platform.claude.com/docs/en/build-with-claude/structured-outputs),
|
|
19
|
+
* and the shape of the SDK's own transform (`@anthropic-ai/sdk` ·
|
|
20
|
+
* `transformJSONSchema`, which moves what the API does not take into the
|
|
21
|
+
* description):
|
|
22
|
+
* - KEPT: `type`, `properties`, `required`, `items`, `anyOf`, `allOf`,
|
|
23
|
+
* local `$ref` with `$defs` / `definitions`, `enum` and `const` of
|
|
24
|
+
* scalars, `default`, `description`, `title`, the ten supported string
|
|
25
|
+
* `format`s, `minItems` of 0 or 1, and a `pattern` with no backreference,
|
|
26
|
+
* lookaround or word boundary. `oneOf` is sent as `anyOf`.
|
|
27
|
+
* - CLOSED: every object gets `additionalProperties: false` — the only value
|
|
28
|
+
* the API takes.
|
|
29
|
+
* - MOVED INTO THE DESCRIPTION, on the wire copy only: every constraint the
|
|
30
|
+
* API does not take (`minimum`, `maximum`, `multipleOf`, `minLength`,
|
|
31
|
+
* `maxLength`, `minItems` above 1 — sent as 1 —, `maxItems`, an
|
|
32
|
+
* unsupported `format` or `pattern`, …). The model still reads them; the
|
|
33
|
+
* parser still enforces them.
|
|
34
|
+
* - REFUSED BY NAME (`NativeOutputSchemaError`): what the API cannot express
|
|
35
|
+
* — a recursive schema, an external or dangling `$ref` (checked on the
|
|
36
|
+
* source AND on the wire copy, whose renamed paths a reference could
|
|
37
|
+
* miss), an `enum` or `const` holding an object or array, `allOf` beside
|
|
38
|
+
* a `$ref`, a node with no type (an open `unknown` value), and an object
|
|
39
|
+
* with open keys (`additionalProperties` given a schema, `true` or `{}`
|
|
40
|
+
* on an object naming no properties, a bare `{ type: 'object' }`, or
|
|
41
|
+
* `patternProperties`: closing it would make every map empty while the
|
|
42
|
+
* parser accepted it).
|
|
43
|
+
* - DROPPED: the meta keys `$schema`, `$id`, `$comment`, `$anchor`.
|
|
44
|
+
*
|
|
45
|
+
* THE RESERVED `_findings` KEY. With `.findings()` armed, the instruction tells
|
|
46
|
+
* the model it may carry its standings on a JSON answer as a top-level
|
|
47
|
+
* `_findings.previous`. Under `additionalProperties: false` a key the schema
|
|
48
|
+
* does not name cannot be written at all, so the answer standings would stop
|
|
49
|
+
* without a sound. Armed, the root gains the optional `_findings` property
|
|
50
|
+
* the served contract allows (`findings/reserved.ts · findingsAnswerSchema`) —
|
|
51
|
+
* unless the author's schema names its own `_findings`, which wins; a root
|
|
52
|
+
* that is not an object cannot carry it and is refused. Unarmed, the schema
|
|
53
|
+
* is the author's alone.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* nativeOutputFormat(
|
|
57
|
+
* { type: 'object', properties: { n: { type: 'integer', minimum: 1 } }, required: ['n'] },
|
|
58
|
+
* { findings: false },
|
|
59
|
+
* );
|
|
60
|
+
* // { type: 'json_schema', schema: { type: 'object',
|
|
61
|
+
* // properties: { n: { type: 'integer', description: '{minimum: 1}' } },
|
|
62
|
+
* // required: ['n'], additionalProperties: false } }
|
|
63
|
+
*/
|
|
64
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
65
|
+
exports.nativeOutputFormat = exports.NativeOutputSchemaError = void 0;
|
|
66
|
+
const reserved_js_1 = require("./findings/reserved.js");
|
|
67
|
+
const types_js_1 = require("./findings/types.js");
|
|
68
|
+
/** A schema the provider's structured output cannot express, named. */
|
|
69
|
+
class NativeOutputSchemaError extends Error {
|
|
70
|
+
/** JSON-pointer-like path of the node refused (`'#'` is the root). */
|
|
71
|
+
path;
|
|
72
|
+
constructor(path, reason) {
|
|
73
|
+
super(`AgentBuilder.outputSchema: strategy 'native' sends the schema as Anthropic's ` +
|
|
74
|
+
`output_config.format, and the node at ${path} cannot be expressed there: ${reason} ` +
|
|
75
|
+
`Change the schema, or use { strategy: 'instruct', retries: N }, which takes any ` +
|
|
76
|
+
`parser and judges the same contract.`);
|
|
77
|
+
this.name = 'NativeOutputSchemaError';
|
|
78
|
+
this.path = path;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.NativeOutputSchemaError = NativeOutputSchemaError;
|
|
82
|
+
const SUPPORTED_FORMATS = new Set([
|
|
83
|
+
'date-time',
|
|
84
|
+
'time',
|
|
85
|
+
'date',
|
|
86
|
+
'duration',
|
|
87
|
+
'email',
|
|
88
|
+
'hostname',
|
|
89
|
+
'uri',
|
|
90
|
+
'ipv4',
|
|
91
|
+
'ipv6',
|
|
92
|
+
'uuid',
|
|
93
|
+
]);
|
|
94
|
+
const META_KEYS = new Set(['$schema', '$id', '$comment', '$anchor']);
|
|
95
|
+
/** Annotations kept as they are (the docs list `default`; the rest are words). */
|
|
96
|
+
const KEPT_AS_IS = new Set(['description', 'title', 'default', 'required']);
|
|
97
|
+
function isObject(value) {
|
|
98
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
99
|
+
}
|
|
100
|
+
function isObjectNode(node) {
|
|
101
|
+
const type = node.type;
|
|
102
|
+
return (type === 'object' ||
|
|
103
|
+
(Array.isArray(type) && type.includes('object')) ||
|
|
104
|
+
isObject(node.properties));
|
|
105
|
+
}
|
|
106
|
+
/** A pattern the API's regex subset refuses: a backreference, lookaround or word boundary. */
|
|
107
|
+
function unsupportedPattern(pattern) {
|
|
108
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
109
|
+
const ch = pattern[i];
|
|
110
|
+
if (ch === '\\') {
|
|
111
|
+
const next = pattern[i + 1];
|
|
112
|
+
if (next !== undefined && /[1-9kbB]/.test(next))
|
|
113
|
+
return true;
|
|
114
|
+
i++;
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (ch === '(' && pattern[i + 1] === '?') {
|
|
118
|
+
const rest = pattern.slice(i + 2, i + 4);
|
|
119
|
+
if (rest.startsWith('=') || rest.startsWith('!') || rest === '<=' || rest === '<!')
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
function deepFreeze(value) {
|
|
126
|
+
if (typeof value === 'object' && value !== null && !Object.isFrozen(value)) {
|
|
127
|
+
Object.freeze(value);
|
|
128
|
+
for (const child of Object.values(value))
|
|
129
|
+
deepFreeze(child);
|
|
130
|
+
}
|
|
131
|
+
return value;
|
|
132
|
+
}
|
|
133
|
+
// ─── Refusals that need the whole schema: $ref resolution ─────────────
|
|
134
|
+
function resolvePointer(root, ref) {
|
|
135
|
+
if (ref === '#')
|
|
136
|
+
return root;
|
|
137
|
+
if (!ref.startsWith('#/'))
|
|
138
|
+
return undefined;
|
|
139
|
+
let node = root;
|
|
140
|
+
for (const raw of ref.slice(2).split('/')) {
|
|
141
|
+
let key;
|
|
142
|
+
try {
|
|
143
|
+
key = decodeURIComponent(raw).replace(/~1/g, '/').replace(/~0/g, '~');
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
return undefined; // a malformed escape points at nothing — refused by name below
|
|
147
|
+
}
|
|
148
|
+
if (typeof node !== 'object' || node === null)
|
|
149
|
+
return undefined;
|
|
150
|
+
node = node[key];
|
|
151
|
+
}
|
|
152
|
+
return node;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Refuse an external, dangling or recursive `$ref`. A depth-first walk that
|
|
156
|
+
* expands each local reference with the chain of references being expanded
|
|
157
|
+
* (`open`); meeting one of them again is recursion. A reference fully
|
|
158
|
+
* expanded once without meeting itself is `settled` and not walked again.
|
|
159
|
+
*/
|
|
160
|
+
function assertReferencesExpressible(root, copy) {
|
|
161
|
+
const settled = new Set();
|
|
162
|
+
const open = new Set();
|
|
163
|
+
const walk = (node, path) => {
|
|
164
|
+
if (Array.isArray(node)) {
|
|
165
|
+
node.forEach((child, i) => walk(child, `${path}/${i}`));
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (!isObject(node))
|
|
169
|
+
return;
|
|
170
|
+
const ref = node.$ref;
|
|
171
|
+
if (typeof ref === 'string') {
|
|
172
|
+
if (!ref.startsWith('#')) {
|
|
173
|
+
throw new NativeOutputSchemaError(path, `'$ref': '${ref}' is an external reference, and only references inside the ` +
|
|
174
|
+
`schema ('#/$defs/…') are supported.`);
|
|
175
|
+
}
|
|
176
|
+
if (open.has(ref)) {
|
|
177
|
+
throw new NativeOutputSchemaError(path, `'$ref': '${ref}' refers back into a definition it is part of — a recursive ` +
|
|
178
|
+
`schema, which is not supported.`);
|
|
179
|
+
}
|
|
180
|
+
if (!settled.has(ref)) {
|
|
181
|
+
const target = resolvePointer(root, ref);
|
|
182
|
+
if (!isObject(target)) {
|
|
183
|
+
throw new NativeOutputSchemaError(path, copy === 'source'
|
|
184
|
+
? `'$ref': '${ref}' points at nothing in this schema.`
|
|
185
|
+
: `'$ref': '${ref}' points into a part of the schema the wire copy does not ` +
|
|
186
|
+
`keep at that path (oneOf is sent as anyOf; keywords the API does not take ` +
|
|
187
|
+
`move into the description). Point it at a $defs entry.`);
|
|
188
|
+
}
|
|
189
|
+
open.add(ref);
|
|
190
|
+
walk(target, ref);
|
|
191
|
+
open.delete(ref);
|
|
192
|
+
settled.add(ref);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Definitions are walked too, referenced or not: a definition that
|
|
196
|
+
// reaches itself is recursive either way, and an unreferenced one is
|
|
197
|
+
// still sent.
|
|
198
|
+
for (const [key, child] of Object.entries(node)) {
|
|
199
|
+
if (key !== '$ref')
|
|
200
|
+
walk(child, `${path}/${key}`);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
open.add('#');
|
|
204
|
+
walk(root, '#');
|
|
205
|
+
}
|
|
206
|
+
// ─── The node transform ───────────────────────────────────────────────
|
|
207
|
+
function describe(node, moved) {
|
|
208
|
+
const entries = Object.entries(moved);
|
|
209
|
+
if (entries.length === 0)
|
|
210
|
+
return;
|
|
211
|
+
const words = `{${entries.map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(', ')}}`;
|
|
212
|
+
const existing = typeof node.description === 'string' ? node.description : undefined;
|
|
213
|
+
node.description = existing ? `${existing}\n\n${words}` : words;
|
|
214
|
+
}
|
|
215
|
+
function transformNode(node, path) {
|
|
216
|
+
if (!isObject(node)) {
|
|
217
|
+
throw new NativeOutputSchemaError(path, 'a schema must be an object, and this one is not.');
|
|
218
|
+
}
|
|
219
|
+
const has = (key) => Object.prototype.hasOwnProperty.call(node, key);
|
|
220
|
+
if (!has('type') &&
|
|
221
|
+
!has('anyOf') &&
|
|
222
|
+
!has('oneOf') &&
|
|
223
|
+
!has('allOf') &&
|
|
224
|
+
!has('$ref') &&
|
|
225
|
+
!has('enum') &&
|
|
226
|
+
!has('const')) {
|
|
227
|
+
throw new NativeOutputSchemaError(path, 'it has no type — an open value (z.unknown(), z.any(), {}) is any JSON at all, which ' +
|
|
228
|
+
'the structured output cannot decode without recursion. Give it a type.');
|
|
229
|
+
}
|
|
230
|
+
if (Array.isArray(node.enum) && node.enum.some((v) => typeof v === 'object' && v !== null)) {
|
|
231
|
+
throw new NativeOutputSchemaError(path, 'its enum holds an object or an array; enum values must be strings, numbers, ' +
|
|
232
|
+
'booleans or null.');
|
|
233
|
+
}
|
|
234
|
+
if (typeof node.const === 'object' && node.const !== null) {
|
|
235
|
+
throw new NativeOutputSchemaError(path, 'its const is an object or an array; a const must be a string, number, boolean or null.');
|
|
236
|
+
}
|
|
237
|
+
if (has('allOf') &&
|
|
238
|
+
Array.isArray(node.allOf) &&
|
|
239
|
+
node.allOf.some((s) => isObject(s) && has$ref(s))) {
|
|
240
|
+
throw new NativeOutputSchemaError(path, 'allOf with a $ref inside it is not supported.');
|
|
241
|
+
}
|
|
242
|
+
// Open keys: a map whose entries the API could never produce once closed.
|
|
243
|
+
// A value schema for the extra keys, a pattern for them, or an object that
|
|
244
|
+
// names no properties and does not say it is closed (`{ type: 'object' }`,
|
|
245
|
+
// `additionalProperties: true` or `{}` — zod's `z.record(…)` emits these).
|
|
246
|
+
const namesNoProperties = !isObject(node.properties) || Object.keys(node.properties).length === 0;
|
|
247
|
+
if (has('patternProperties') ||
|
|
248
|
+
(isObject(node.additionalProperties) && Object.keys(node.additionalProperties).length > 0) ||
|
|
249
|
+
(isObjectNode(node) && namesNoProperties && node.additionalProperties !== false)) {
|
|
250
|
+
throw new NativeOutputSchemaError(path, 'it is an object with open keys (a record or map: additionalProperties given a schema ' +
|
|
251
|
+
'or left open, or patternProperties). The API takes only additionalProperties: false, ' +
|
|
252
|
+
'which would make every such map empty while the parser accepted it. Name the keys as ' +
|
|
253
|
+
'properties.');
|
|
254
|
+
}
|
|
255
|
+
// A reference stands alone, as the SDK's transform sends it: its target
|
|
256
|
+
// carries the shape, and siblings beside a `$ref` are not part of the subset
|
|
257
|
+
// — except the definitions it may point into (a root `$ref` beside its
|
|
258
|
+
// `definitions`, as zod-to-json-schema writes with a name).
|
|
259
|
+
if (has('$ref')) {
|
|
260
|
+
const ref = { $ref: node.$ref };
|
|
261
|
+
for (const key of ['$defs', 'definitions']) {
|
|
262
|
+
if (isObject(node[key]))
|
|
263
|
+
ref[key] = transformDefinitions(node[key], `${path}/${key}`);
|
|
264
|
+
}
|
|
265
|
+
return ref;
|
|
266
|
+
}
|
|
267
|
+
const out = {};
|
|
268
|
+
const moved = {};
|
|
269
|
+
for (const [key, value] of Object.entries(node)) {
|
|
270
|
+
if (META_KEYS.has(key))
|
|
271
|
+
continue;
|
|
272
|
+
switch (key) {
|
|
273
|
+
case 'type':
|
|
274
|
+
case 'enum':
|
|
275
|
+
case 'const':
|
|
276
|
+
out[key] = value;
|
|
277
|
+
break;
|
|
278
|
+
case 'properties':
|
|
279
|
+
if (isObject(value)) {
|
|
280
|
+
out.properties = Object.fromEntries(Object.entries(value).map(([name, child]) => [
|
|
281
|
+
name,
|
|
282
|
+
transformNode(child, `${path}/properties/${name}`),
|
|
283
|
+
]));
|
|
284
|
+
}
|
|
285
|
+
else
|
|
286
|
+
moved[key] = value;
|
|
287
|
+
break;
|
|
288
|
+
case 'items':
|
|
289
|
+
if (isObject(value))
|
|
290
|
+
out.items = transformNode(value, `${path}/items`);
|
|
291
|
+
else
|
|
292
|
+
moved[key] = value;
|
|
293
|
+
break;
|
|
294
|
+
case 'anyOf':
|
|
295
|
+
case 'oneOf':
|
|
296
|
+
case 'allOf':
|
|
297
|
+
if (Array.isArray(value)) {
|
|
298
|
+
const target = key === 'allOf' ? 'allOf' : 'anyOf';
|
|
299
|
+
out[target] = value.map((child, i) => transformNode(child, `${path}/${key}/${i}`));
|
|
300
|
+
}
|
|
301
|
+
else
|
|
302
|
+
moved[key] = value;
|
|
303
|
+
break;
|
|
304
|
+
case '$defs':
|
|
305
|
+
case 'definitions':
|
|
306
|
+
if (isObject(value))
|
|
307
|
+
out[key] = transformDefinitions(value, `${path}/${key}`);
|
|
308
|
+
else
|
|
309
|
+
moved[key] = value;
|
|
310
|
+
break;
|
|
311
|
+
case 'format':
|
|
312
|
+
if (SUPPORTED_FORMATS.has(value))
|
|
313
|
+
out.format = value;
|
|
314
|
+
else
|
|
315
|
+
moved[key] = value;
|
|
316
|
+
break;
|
|
317
|
+
case 'pattern':
|
|
318
|
+
if (typeof value === 'string' && !unsupportedPattern(value))
|
|
319
|
+
out.pattern = value;
|
|
320
|
+
else
|
|
321
|
+
moved[key] = value;
|
|
322
|
+
break;
|
|
323
|
+
case 'minItems':
|
|
324
|
+
if (value === 0 || value === 1)
|
|
325
|
+
out.minItems = value;
|
|
326
|
+
else {
|
|
327
|
+
moved[key] = value;
|
|
328
|
+
if (typeof value === 'number' && value > 1)
|
|
329
|
+
out.minItems = 1;
|
|
330
|
+
}
|
|
331
|
+
break;
|
|
332
|
+
case 'additionalProperties':
|
|
333
|
+
// `true`, `{}` or `false`: closed below. A schema was refused above.
|
|
334
|
+
break;
|
|
335
|
+
default:
|
|
336
|
+
if (KEPT_AS_IS.has(key))
|
|
337
|
+
out[key] = value;
|
|
338
|
+
else
|
|
339
|
+
moved[key] = value;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
if (isObjectNode(node)) {
|
|
343
|
+
if (out.properties === undefined)
|
|
344
|
+
out.properties = {};
|
|
345
|
+
out.additionalProperties = false;
|
|
346
|
+
}
|
|
347
|
+
describe(out, moved);
|
|
348
|
+
return out;
|
|
349
|
+
}
|
|
350
|
+
function transformDefinitions(defs, path) {
|
|
351
|
+
return Object.fromEntries(Object.entries(defs).map(([name, child]) => [name, transformNode(child, `${path}/${name}`)]));
|
|
352
|
+
}
|
|
353
|
+
function has$ref(node) {
|
|
354
|
+
return Object.prototype.hasOwnProperty.call(node, '$ref');
|
|
355
|
+
}
|
|
356
|
+
// ─── The one entry point ──────────────────────────────────────────────
|
|
357
|
+
/**
|
|
358
|
+
* The structured-output format for `jsonSchema`, made API-compatible as the
|
|
359
|
+
* file header lists, with the reserved `_findings` property when the findings
|
|
360
|
+
* ledger is armed. Deep-frozen; the input is never edited.
|
|
361
|
+
*
|
|
362
|
+
* @throws NativeOutputSchemaError naming the node the API cannot express.
|
|
363
|
+
*/
|
|
364
|
+
function nativeOutputFormat(jsonSchema, arms) {
|
|
365
|
+
let source = jsonSchema;
|
|
366
|
+
if (arms.findings) {
|
|
367
|
+
if (!isObjectNode(jsonSchema)) {
|
|
368
|
+
throw new NativeOutputSchemaError('#', `.findings() lets a JSON answer carry its standings as a top-level ` +
|
|
369
|
+
`'${types_js_1.RESERVED_ANSWER_KEY}' property, and this root is not an object schema with ` +
|
|
370
|
+
`properties, so the structured output would refuse the key and the standings would ` +
|
|
371
|
+
`stop. Give the answer an object root.`);
|
|
372
|
+
}
|
|
373
|
+
const properties = isObject(jsonSchema.properties) ? jsonSchema.properties : {};
|
|
374
|
+
if (!Object.prototype.hasOwnProperty.call(properties, types_js_1.RESERVED_ANSWER_KEY)) {
|
|
375
|
+
source = {
|
|
376
|
+
...jsonSchema,
|
|
377
|
+
properties: { ...properties, [types_js_1.RESERVED_ANSWER_KEY]: (0, reserved_js_1.findingsAnswerSchema)() },
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
assertReferencesExpressible(source, 'source');
|
|
382
|
+
const schema = transformNode(source, '#');
|
|
383
|
+
// And again on what is SENT: a reference into a path the copy renamed or
|
|
384
|
+
// moved would dangle on the wire, a 400 on every call.
|
|
385
|
+
assertReferencesExpressible(schema, 'wire');
|
|
386
|
+
return deepFreeze({ type: 'json_schema', schema });
|
|
387
|
+
}
|
|
388
|
+
exports.nativeOutputFormat = nativeOutputFormat;
|
|
389
|
+
//# sourceMappingURL=nativeOutputFormat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nativeOutputFormat.js","sourceRoot":"","sources":["../../../src/core/agent/nativeOutputFormat.ts"],"names":[],"mappings":"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"}
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
* Identical reasoning, identical shape, to the compaction frame.
|
|
36
36
|
*/
|
|
37
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
exports.judgeAnswer = exports.resolveJsonSchema = exports.readSchemaToolAnswer = exports.buildSchemaTool = exports.SCHEMA_TOOL_NAME = exports.correctiveMessageHash = exports.isSchemaCheckMessage = exports.buildCorrectiveTurn = exports.SCHEMA_CHECK_FRAME_PREFIX = exports.describeFailure = exports.recordOutputAttempt = void 0;
|
|
38
|
+
exports.judgeAnswer = exports.resolveJsonSchema = exports.readSchemaToolAnswer = exports.buildSchemaTool = exports.SCHEMA_TOOL_NAME = exports.correctiveMessageHash = exports.isSchemaCheckMessage = exports.buildCorrectiveTurn = exports.SCHEMA_CHECK_FRAME_PREFIX = exports.describeFailure = exports.nativeStopFailure = exports.recordOutputAttempt = void 0;
|
|
39
39
|
const helpers_js_1 = require("../slots/helpers.js");
|
|
40
40
|
const outputSchema_js_1 = require("../outputSchema.js");
|
|
41
41
|
const saidByPerson_js_1 = require("../../lib/saidByPerson.js");
|
|
@@ -54,6 +54,40 @@ function recordOutputAttempt(scope, row) {
|
|
|
54
54
|
scope.outputAttempts = [...prev, row];
|
|
55
55
|
}
|
|
56
56
|
exports.recordOutputAttempt = recordOutputAttempt;
|
|
57
|
+
/**
|
|
58
|
+
* Fail a `strategy: 'native'` answer by its stop reason, before the parser.
|
|
59
|
+
*
|
|
60
|
+
* Anthropic's structured-outputs page: on `stop_reason: "refusal"` "the output
|
|
61
|
+
* may not match your schema because the refusal message takes precedence",
|
|
62
|
+
* and on `"max_tokens"` "the output may be incomplete and not match your
|
|
63
|
+
* schema". So the format was not in force for this text, and an answer that
|
|
64
|
+
* happens to parse is still not one the format produced — delivering it as
|
|
65
|
+
* constrained would be a silent pass. Returns `undefined` under any other
|
|
66
|
+
* strategy or stop. The words are the library's own, naming the stop; the
|
|
67
|
+
* failure then takes the ordinary path (retry, or exhausted and unmet).
|
|
68
|
+
*/
|
|
69
|
+
function nativeStopFailure(enforcement, stopReason) {
|
|
70
|
+
if (enforcement.outputFormat === undefined)
|
|
71
|
+
return undefined;
|
|
72
|
+
if (stopReason !== 'refusal' &&
|
|
73
|
+
stopReason !== 'max_tokens' &&
|
|
74
|
+
stopReason !== 'model_context_window_exceeded')
|
|
75
|
+
return undefined;
|
|
76
|
+
// Quoted to the model on a re-ask (`buildCorrectiveTurn`), so it states the
|
|
77
|
+
// past fact only — no advice to the developer, no destination.
|
|
78
|
+
return {
|
|
79
|
+
stage: 'schema-validate',
|
|
80
|
+
error: stopReason === 'refusal'
|
|
81
|
+
? "The provider stopped with stop_reason 'refusal': the model declined, and the " +
|
|
82
|
+
'structured-output format does not hold for a refusal, so this text is not accepted ' +
|
|
83
|
+
'as the answer even where it parses.'
|
|
84
|
+
: `The provider stopped with stop_reason '${stopReason}': the answer was cut off ` +
|
|
85
|
+
'before it was complete, so the structured-output format does not hold for it and it ' +
|
|
86
|
+
'is not accepted even where it parses.',
|
|
87
|
+
stopReason,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
exports.nativeStopFailure = nativeStopFailure;
|
|
57
91
|
/**
|
|
58
92
|
* Flatten whatever the parser threw into {@link OutputFailure}.
|
|
59
93
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outputEnforcement.js","sourceRoot":"","sources":["../../../src/core/agent/outputEnforcement.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;;;AAGH,oDAA4C;AAC5C,wDAAgF;AAChF,+DAAsE;AACtE,mEAAqF;
|
|
1
|
+
{"version":3,"file":"outputEnforcement.js","sourceRoot":"","sources":["../../../src/core/agent/outputEnforcement.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ const index_js_1 = require("../../../answer-validation/index.js");
|
|
|
10
10
|
* as its result, and a composition mounting the chart took `'final'` for the
|
|
11
11
|
* agent's answer. Routed on, the chart ends with no answer and the verdict in
|
|
12
12
|
* its state (`core/terminalVerdict.ts`). */
|
|
13
|
-
function withAnswerValidation(decide, config, parser, store, hasOutstandingConsent) {
|
|
13
|
+
function withAnswerValidation(decide, config, parser, store, hasOutstandingConsent, nativeOutput = false) {
|
|
14
14
|
if (parser === undefined) {
|
|
15
15
|
throw new Error('Agent.answerValidation requires .outputSchema(parser).');
|
|
16
16
|
}
|
|
@@ -18,9 +18,14 @@ function withAnswerValidation(decide, config, parser, store, hasOutstandingConse
|
|
|
18
18
|
const branch = await decide(scope);
|
|
19
19
|
if (branch !== 'final')
|
|
20
20
|
return branch;
|
|
21
|
+
// `strategy: 'native'` only (read only then, so other agents keep their
|
|
22
|
+
// bytes): an answer whose attempt the Route decider failed on a provider
|
|
23
|
+
// stop ('refusal', 'max_tokens') may still parse — it is not schema-accepted.
|
|
24
|
+
const nativeStop = nativeOutput ? scope.outputContractUnmet?.stopReason : undefined;
|
|
21
25
|
const priorRefusal = scope.messageDeniedReason !== undefined ||
|
|
22
26
|
scope.unsupportedValues?.refused === true ||
|
|
23
|
-
hasOutstandingConsent()
|
|
27
|
+
hasOutstandingConsent() ||
|
|
28
|
+
nativeStop !== undefined;
|
|
24
29
|
if (priorRefusal) {
|
|
25
30
|
const report = {
|
|
26
31
|
validatorId: config.id,
|
|
@@ -34,10 +39,15 @@ function withAnswerValidation(decide, config, parser, store, hasOutstandingConse
|
|
|
34
39
|
checks: [],
|
|
35
40
|
resolvedRefs: [],
|
|
36
41
|
schemaAccepted: false,
|
|
37
|
-
reason: 'prior-refusal',
|
|
42
|
+
reason: nativeStop !== undefined ? `provider-stop:${nativeStop}` : 'prior-refusal',
|
|
38
43
|
};
|
|
39
44
|
scope.answerValidation = report;
|
|
40
|
-
|
|
45
|
+
// A provider stop is the schema's verdict, not a refusal by a rule: it
|
|
46
|
+
// withholds only in `enforce` — `observe` hands the answer back with
|
|
47
|
+
// the report, as the same agent without validation would.
|
|
48
|
+
if (nativeStop === undefined || config.mode === 'enforce') {
|
|
49
|
+
scope.answerValidationBlocked = true;
|
|
50
|
+
}
|
|
41
51
|
return 'final';
|
|
42
52
|
}
|
|
43
53
|
const identity = scope.runIdentity;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"answerValidation.js","sourceRoot":"","sources":["../../../../src/core/agent/stages/answerValidation.ts"],"names":[],"mappings":";;;AACA,kEAI6C;AAM7C;;;;;;;4CAO4C;AAC5C,SAAgB,oBAAoB,CAClC,MAA6E,EAC7E,MAAgC,EAChC,MAA+C,EAC/C,KAAgC,EAChC,qBAAoC;
|
|
1
|
+
{"version":3,"file":"answerValidation.js","sourceRoot":"","sources":["../../../../src/core/agent/stages/answerValidation.ts"],"names":[],"mappings":";;;AACA,kEAI6C;AAM7C;;;;;;;4CAO4C;AAC5C,SAAgB,oBAAoB,CAClC,MAA6E,EAC7E,MAAgC,EAChC,MAA+C,EAC/C,KAAgC,EAChC,qBAAoC,EACpC,YAAY,GAAG,KAAK;IAEpB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,KAAK,EAAE,KAAK,EAAE,EAAE;QACrB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,MAAM,KAAK,OAAO;YAAE,OAAO,MAAM,CAAC;QACtC,wEAAwE;QACxE,yEAAyE;QACzE,8EAA8E;QAC9E,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;QACpF,MAAM,YAAY,GAChB,KAAK,CAAC,mBAAmB,KAAK,SAAS;YACvC,KAAK,CAAC,iBAAiB,EAAE,OAAO,KAAK,IAAI;YACzC,qBAAqB,EAAE;YACvB,UAAU,KAAK,SAAS,CAAC;QAC3B,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,MAAM,GAA2B;gBACrC,WAAW,EAAE,MAAM,CAAC,EAAE;gBACtB,gBAAgB,EAAE,MAAM,CAAC,OAAO;gBAChC,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,MAAM,EAAE,YAAY;gBACpB,OAAO,EAAE,CAAC;gBACV,MAAM,EAAE,CAAC;gBACT,WAAW,EAAE,CAAC;gBACd,aAAa,EAAE,CAAC;gBAChB,MAAM,EAAE,EAAE;gBACV,YAAY,EAAE,EAAE;gBAChB,cAAc,EAAE,KAAK;gBACrB,MAAM,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,iBAAiB,UAAU,EAAE,CAAC,CAAC,CAAC,eAAe;aACnF,CAAC;YACF,KAAK,CAAC,gBAAgB,GAAG,MAAM,CAAC;YAChC,uEAAuE;YACvE,qEAAqE;YACrE,0DAA0D;YAC1D,IAAI,UAAU,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC1D,KAAK,CAAC,uBAAuB,GAAG,IAAI,CAAC;YACvC,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,IAAA,kCAAuB,EAC1C,KAAK,CAAC,gBAAgB,EACtB,MAAM,EACN,MAAM,EACN,KAAK,EACL;YACE,cAAc,EAAE,QAAQ,CAAC,cAAc;YACvC,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;YACjE,GAAG,CAAC,QAAQ,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC;SAC3E,EACD,KAAK,CAAC,OAAO,EAAE,CAAC,MAAM,CACvB,CAAC;QACF,KAAK,CAAC,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC;QACvC,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACnE,KAAK,CAAC,uBAAuB,GAAG,IAAI,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,gBAAgB,GAAG,MAAM,CAAC,OAAO,IAAI,KAAK,CAAC,gBAAgB,CAAC;QACpE,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;AACJ,CAAC;AApED,oDAoEC"}
|
|
@@ -46,6 +46,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
46
46
|
exports.buildCallLLMStage = void 0;
|
|
47
47
|
const iterationBudget_js_1 = require("../../../lib/iterationBudget.js");
|
|
48
48
|
const forcedToolChoice_js_1 = require("../../../adapters/forcedToolChoice.js");
|
|
49
|
+
const nativeOutputSchema_js_1 = require("../../../adapters/nativeOutputSchema.js");
|
|
49
50
|
const typedEmit_js_1 = require("../../../recorders/core/typedEmit.js");
|
|
50
51
|
const wire_js_1 = require("../../../integrity/invariant-violation/wire.js");
|
|
51
52
|
const check_js_1 = require("../../../integrity/dangling-reference/check.js");
|
|
@@ -74,6 +75,11 @@ function assertForcedRequestSupported(provider, request) {
|
|
|
74
75
|
if (request.toolChoice !== undefined && !(0, forcedToolChoice_js_1.forcedToolChoiceFor)(provider, request.model)) {
|
|
75
76
|
throw new forcedToolChoice_js_1.UnsupportedToolChoiceError({ provider: provider.name, model: request.model });
|
|
76
77
|
}
|
|
78
|
+
// The structured-output twin (`strategy: 'native'`), judged on the same
|
|
79
|
+
// effective model — a configured or per-skill model included.
|
|
80
|
+
if (request.outputFormat !== undefined && !(0, nativeOutputSchema_js_1.nativeOutputSchemaFor)(provider, request.model)) {
|
|
81
|
+
throw new nativeOutputSchema_js_1.UnsupportedNativeOutputError({ provider: provider.name, model: request.model });
|
|
82
|
+
}
|
|
77
83
|
}
|
|
78
84
|
/**
|
|
79
85
|
* Consult the app's external-ground provider, throw-proof by law (9.72.0): a
|
|
@@ -410,6 +416,7 @@ function buildCallLLMStage(deps) {
|
|
|
410
416
|
...(deps.schemaTool !== undefined && {
|
|
411
417
|
toolChoice: { type: 'tool', name: deps.schemaTool.name },
|
|
412
418
|
}),
|
|
419
|
+
...(deps.outputFormat !== undefined && { outputFormat: deps.outputFormat }),
|
|
413
420
|
};
|
|
414
421
|
// v2.6+ — call cache strategy to attach provider-specific cache
|
|
415
422
|
// hints. CacheGate has already routed (apply-markers / no-markers)
|
|
@@ -740,8 +747,25 @@ function buildCallLLMStage(deps) {
|
|
|
740
747
|
if (typeof response.usage.cacheRead === 'number') {
|
|
741
748
|
scope.totalCacheReadTokens = (scope.totalCacheReadTokens ?? 0) + response.usage.cacheRead;
|
|
742
749
|
}
|
|
750
|
+
// `'native'` only. A provider that states its manifest (wireManifest.ts)
|
|
751
|
+
// and says no format crossed sent the request unconstrained while it
|
|
752
|
+
// declared the capability — refused, never delivered as constrained.
|
|
753
|
+
if (deps.outputFormat !== undefined &&
|
|
754
|
+
response.wireManifest !== undefined &&
|
|
755
|
+
response.wireManifest.outputFormat === undefined) {
|
|
756
|
+
throw new Error(`Agent: .outputSchema(parser, { strategy: 'native' }) — '${answeredBy.provider}' ` +
|
|
757
|
+
`declares a native structured-output format, but its wire manifest says the request ` +
|
|
758
|
+
`it sent carried none. The answer was not constrained, so it is not delivered as if ` +
|
|
759
|
+
`it were.`);
|
|
760
|
+
}
|
|
743
761
|
scope.llmLatestContent = response.content;
|
|
744
762
|
scope.llmLatestToolCalls = response.toolCalls;
|
|
763
|
+
// `'native'` only, every call (so it is never stale): the stop reason the
|
|
764
|
+
// Route decider judges a constrained answer by — a 'refusal' or
|
|
765
|
+
// 'max_tokens' stop does not hold the format (outputEnforcement.ts ·
|
|
766
|
+
// nativeStopFailure). Absent on every other agent, so their bytes are unchanged.
|
|
767
|
+
if (deps.outputFormat !== undefined)
|
|
768
|
+
scope.llmLatestStopReason = response.stopReason;
|
|
745
769
|
// A response owns its replay evidence, never the previous response's.
|
|
746
770
|
// The presence trap does not record a read on never-replay providers.
|
|
747
771
|
if (response.replay !== undefined || 'llmLatestReplay' in scope) {
|