@agen-ai/agent-protocol 0.4.2 → 0.4.4
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/README.md +151 -21
- package/dist/capabilities/types.d.ts +3 -1
- package/dist/events/types.d.ts +1 -1
- package/dist/foundation/types.d.ts +2 -1
- package/dist/foundation/types.js +1 -1
- package/dist/jsonSchema/generated.d.ts +13637 -9890
- package/dist/jsonSchema/generated.js +3025 -644
- package/dist/public/index.d.ts +1 -0
- package/dist/public/index.js +1 -0
- package/dist/public/structuredOutput.d.ts +2 -0
- package/dist/public/structuredOutput.js +1 -0
- package/dist/sessions/types.d.ts +2 -0
- package/dist/structuredOutput/boundedJson.d.ts +13 -0
- package/dist/structuredOutput/boundedJson.js +143 -0
- package/dist/structuredOutput/constants.d.ts +24 -0
- package/dist/structuredOutput/constants.js +57 -0
- package/dist/structuredOutput/definition.d.ts +9 -0
- package/dist/structuredOutput/definition.js +15 -0
- package/dist/structuredOutput/index.d.ts +9 -0
- package/dist/structuredOutput/index.js +12 -0
- package/dist/structuredOutput/issues.d.ts +8 -0
- package/dist/structuredOutput/issues.js +76 -0
- package/dist/structuredOutput/parsers.d.ts +10 -0
- package/dist/structuredOutput/parsers.js +74 -0
- package/dist/structuredOutput/schemaAdmission.d.ts +9 -0
- package/dist/structuredOutput/schemaAdmission.js +247 -0
- package/dist/structuredOutput/types.d.ts +75 -0
- package/dist/structuredOutput/types.js +0 -0
- package/dist/structuredOutput/values.d.ts +5 -0
- package/dist/structuredOutput/values.js +89 -0
- package/dist/turns/types.d.ts +18 -5
- package/dist/zod/capabilities.d.ts +3 -2
- package/dist/zod/capabilities.js +2 -0
- package/dist/zod/events.d.ts +24 -33
- package/dist/zod/events.js +94 -94
- package/dist/zod/foundation.d.ts +1 -0
- package/dist/zod/foundation.js +3 -0
- package/dist/zod/index.d.ts +2 -0
- package/dist/zod/index.js +25 -1
- package/dist/zod/operations.d.ts +2 -2
- package/dist/zod/outputDefinition.d.ts +4 -0
- package/dist/zod/outputDefinition.js +22 -0
- package/dist/zod/outputSchema.d.ts +4 -0
- package/dist/zod/outputSchema.js +177 -0
- package/dist/zod/sessions.d.ts +14 -0
- package/dist/zod/sessions.js +26 -3
- package/dist/zod/structuredOutput.d.ts +14 -0
- package/dist/zod/structuredOutput.js +209 -0
- package/dist/zod/turns.d.ts +19 -5
- package/dist/zod/turns.js +63 -24
- package/dist/zod/typeEquality.generated.d.ts +16 -2
- package/package.json +6 -2
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AGENT_OUTPUT_SCHEMA_BYTES_LIMIT,
|
|
3
|
+
AGENT_OUTPUT_SCHEMA_DEPTH_LIMIT,
|
|
4
|
+
AGENT_OUTPUT_SCHEMA_DESCRIPTION_MAX_LENGTH,
|
|
5
|
+
AGENT_OUTPUT_SCHEMA_DIALECT,
|
|
6
|
+
AGENT_OUTPUT_SCHEMA_ENUM_VALUES_LIMIT,
|
|
7
|
+
AGENT_OUTPUT_SCHEMA_LENGTH_BOUND_LIMIT,
|
|
8
|
+
AGENT_OUTPUT_SCHEMA_NODES_LIMIT,
|
|
9
|
+
AGENT_OUTPUT_VALUE_BYTES_LIMIT,
|
|
10
|
+
AGENT_OUTPUT_VALUE_COLLECTION_LIMIT,
|
|
11
|
+
AGENT_OUTPUT_VALUE_DEPTH_LIMIT,
|
|
12
|
+
AGENT_OUTPUT_VALUE_NODES_LIMIT
|
|
13
|
+
} from "./constants.js";
|
|
14
|
+
import { codePointLength, isJsonObject, serializedStringBytes } from "./boundedJson.js";
|
|
15
|
+
class StructuredOutputSchemaError extends Error {
|
|
16
|
+
constructor(message, path) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.message = message;
|
|
19
|
+
this.path = path;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function invalid(message, path) {
|
|
23
|
+
throw new StructuredOutputSchemaError(message, path);
|
|
24
|
+
}
|
|
25
|
+
function object(value, path) {
|
|
26
|
+
if (value === void 0 || !isJsonObject(value)) invalid("A schema node must be a plain object.", path);
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
function keys(value, allowed, path) {
|
|
30
|
+
if (Object.keys(value).some((key) => !allowed.includes(key))) invalid("Schema contains an unsupported keyword.", path);
|
|
31
|
+
}
|
|
32
|
+
function description(value, path) {
|
|
33
|
+
if (!Object.hasOwn(value, "description")) return {};
|
|
34
|
+
if (typeof value.description !== "string" || codePointLength(value.description) > AGENT_OUTPUT_SCHEMA_DESCRIPTION_MAX_LENGTH) {
|
|
35
|
+
invalid("Schema descriptions must be strings within the code-point limit.", [...path, "description"]);
|
|
36
|
+
}
|
|
37
|
+
return { description: value.description };
|
|
38
|
+
}
|
|
39
|
+
function bound(value, key, path, integer) {
|
|
40
|
+
if (!Object.hasOwn(value, key)) return void 0;
|
|
41
|
+
const candidate = value[key];
|
|
42
|
+
if (typeof candidate !== "number" || !Number.isFinite(candidate) || integer && (!Number.isSafeInteger(candidate) || candidate < 0 || candidate > AGENT_OUTPUT_SCHEMA_LENGTH_BOUND_LIMIT)) {
|
|
43
|
+
invalid(integer ? "Length bounds must be nonnegative safe integers within the profile ceiling." : "Numeric bounds must be finite numbers.", [...path, key]);
|
|
44
|
+
}
|
|
45
|
+
return candidate;
|
|
46
|
+
}
|
|
47
|
+
function ordered(minimum, maximum, path) {
|
|
48
|
+
if (minimum !== void 0 && maximum !== void 0 && minimum > maximum) invalid("Schema minimum must not exceed maximum.", path);
|
|
49
|
+
}
|
|
50
|
+
function isNullSchema(value) {
|
|
51
|
+
return "type" in value && value.type === "null";
|
|
52
|
+
}
|
|
53
|
+
function isNonNullSchema(value) {
|
|
54
|
+
return "type" in value && value.type !== "null";
|
|
55
|
+
}
|
|
56
|
+
function admitOutputSchema(input, maxOutputBytes = AGENT_OUTPUT_VALUE_BYTES_LIMIT) {
|
|
57
|
+
let nodes = 0;
|
|
58
|
+
function node(value, depth, path, root = false) {
|
|
59
|
+
nodes += 1;
|
|
60
|
+
if (nodes > AGENT_OUTPUT_SCHEMA_NODES_LIMIT || depth > AGENT_OUTPUT_SCHEMA_DEPTH_LIMIT) {
|
|
61
|
+
invalid("Schema exceeds the node or depth limit.", path);
|
|
62
|
+
}
|
|
63
|
+
const source = object(value, path);
|
|
64
|
+
const annotation = description(source, path);
|
|
65
|
+
if (Object.hasOwn(source, "anyOf")) {
|
|
66
|
+
keys(source, ["anyOf", "description"], path);
|
|
67
|
+
if (root) invalid("The output schema root must be an object.", path);
|
|
68
|
+
const branches = source.anyOf;
|
|
69
|
+
if (!Array.isArray(branches) || branches.length !== 2) invalid("Nullable schemas require exactly one non-null and one null branch.", [...path, "anyOf"]);
|
|
70
|
+
const firstValue = branches[0];
|
|
71
|
+
const secondValue = branches[1];
|
|
72
|
+
if (firstValue === void 0 || secondValue === void 0) invalid("Nullable branches must be present.", [...path, "anyOf"]);
|
|
73
|
+
const first = node(firstValue, depth + 1, [...path, "anyOf", 0]);
|
|
74
|
+
const second = node(secondValue, depth + 1, [...path, "anyOf", 1]);
|
|
75
|
+
if (isNonNullSchema(first) && isNullSchema(second)) return Object.freeze({ anyOf: Object.freeze([first, second]), ...annotation });
|
|
76
|
+
if (isNullSchema(first) && isNonNullSchema(second)) return Object.freeze({ anyOf: Object.freeze([second, first]), ...annotation });
|
|
77
|
+
invalid("Nullable schemas require one non-null branch and prohibit nested nullable wrappers.", [...path, "anyOf"]);
|
|
78
|
+
}
|
|
79
|
+
if (root && source.type !== "object") invalid("The output schema root must be an object.", path);
|
|
80
|
+
const dialect = root ? ["$schema"] : [];
|
|
81
|
+
if (root && Object.hasOwn(source, "$schema") && source.$schema !== AGENT_OUTPUT_SCHEMA_DIALECT) invalid("Only JSON Schema draft 2020-12 is supported.", [...path, "$schema"]);
|
|
82
|
+
switch (source.type) {
|
|
83
|
+
case "object": {
|
|
84
|
+
keys(source, ["type", "properties", "required", "additionalProperties", "description", ...dialect], path);
|
|
85
|
+
const properties = object(source.properties, [...path, "properties"]);
|
|
86
|
+
const required = source.required;
|
|
87
|
+
if (source.additionalProperties !== false || !Array.isArray(required)) invalid("Object schemas must be closed and explicitly require every property.", path);
|
|
88
|
+
const names = Object.keys(properties);
|
|
89
|
+
const requiredNames = /* @__PURE__ */ new Set();
|
|
90
|
+
for (const candidate of required) {
|
|
91
|
+
if (typeof candidate !== "string" || requiredNames.has(candidate) || !Object.hasOwn(properties, candidate)) {
|
|
92
|
+
invalid("Required keys must name every property exactly once.", [...path, "required"]);
|
|
93
|
+
}
|
|
94
|
+
requiredNames.add(candidate);
|
|
95
|
+
}
|
|
96
|
+
if (requiredNames.size !== names.length) invalid("Required keys must name every property exactly once.", [...path, "required"]);
|
|
97
|
+
const parsed = {};
|
|
98
|
+
for (const name of names) {
|
|
99
|
+
const child = properties[name];
|
|
100
|
+
if (child === void 0) invalid("Object properties require schema nodes.", [...path, "properties", name]);
|
|
101
|
+
parsed[name] = node(child, depth + 1, [...path, "properties", name]);
|
|
102
|
+
}
|
|
103
|
+
return Object.freeze({ type: "object", properties: Object.freeze(parsed), required: Object.freeze(names), additionalProperties: false, ...annotation });
|
|
104
|
+
}
|
|
105
|
+
case "array": {
|
|
106
|
+
keys(source, ["type", "items", "minItems", "maxItems", "description"], path);
|
|
107
|
+
const minItems = bound(source, "minItems", path, true);
|
|
108
|
+
const maxItems = bound(source, "maxItems", path, true);
|
|
109
|
+
ordered(minItems, maxItems, path);
|
|
110
|
+
if (minItems !== void 0 && minItems > AGENT_OUTPUT_VALUE_COLLECTION_LIMIT) invalid("Array minimum cannot exceed the value collection limit.", [...path, "minItems"]);
|
|
111
|
+
const item = source.items;
|
|
112
|
+
if (item === void 0) invalid("Array schemas require one homogeneous item schema.", [...path, "items"]);
|
|
113
|
+
return Object.freeze({
|
|
114
|
+
type: "array",
|
|
115
|
+
items: node(item, depth + 1, [...path, "items"]),
|
|
116
|
+
...minItems === void 0 ? {} : { minItems },
|
|
117
|
+
...maxItems === void 0 ? {} : { maxItems },
|
|
118
|
+
...annotation
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
case "string": {
|
|
122
|
+
keys(source, ["type", "enum", "minLength", "maxLength", "description"], path);
|
|
123
|
+
const minLength = bound(source, "minLength", path, true);
|
|
124
|
+
const maxLength = bound(source, "maxLength", path, true);
|
|
125
|
+
ordered(minLength, maxLength, path);
|
|
126
|
+
let values;
|
|
127
|
+
if (Object.hasOwn(source, "enum")) {
|
|
128
|
+
const candidates = source.enum;
|
|
129
|
+
if (!Array.isArray(candidates) || candidates.length === 0 || candidates.length > AGENT_OUTPUT_SCHEMA_ENUM_VALUES_LIMIT) invalid("String enums must be nonempty and bounded.", [...path, "enum"]);
|
|
130
|
+
const strings = [];
|
|
131
|
+
const unique = /* @__PURE__ */ new Set();
|
|
132
|
+
for (const candidate of candidates) {
|
|
133
|
+
if (typeof candidate !== "string" || unique.has(candidate)) invalid("String enums require unique strings.", [...path, "enum"]);
|
|
134
|
+
const length = codePointLength(candidate);
|
|
135
|
+
if (minLength !== void 0 && length < minLength || maxLength !== void 0 && length > maxLength) invalid("Every enum value must satisfy the string length bounds.", [...path, "enum"]);
|
|
136
|
+
unique.add(candidate);
|
|
137
|
+
strings.push(candidate);
|
|
138
|
+
}
|
|
139
|
+
const [first, ...rest] = strings;
|
|
140
|
+
if (first === void 0) invalid("String enums cannot be empty.", [...path, "enum"]);
|
|
141
|
+
values = Object.freeze([first, ...rest]);
|
|
142
|
+
}
|
|
143
|
+
return Object.freeze({
|
|
144
|
+
type: "string",
|
|
145
|
+
...values === void 0 ? {} : { enum: values },
|
|
146
|
+
...minLength === void 0 ? {} : { minLength },
|
|
147
|
+
...maxLength === void 0 ? {} : { maxLength },
|
|
148
|
+
...annotation
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
case "number":
|
|
152
|
+
case "integer": {
|
|
153
|
+
keys(source, ["type", "minimum", "maximum", "description"], path);
|
|
154
|
+
const minimum2 = bound(source, "minimum", path, false);
|
|
155
|
+
const maximum = bound(source, "maximum", path, false);
|
|
156
|
+
ordered(minimum2, maximum, path);
|
|
157
|
+
if (source.type === "integer" && minimum2 !== void 0 && maximum !== void 0 && Math.ceil(minimum2) > Math.floor(maximum)) invalid("Integer bounds admit no integer value.", path);
|
|
158
|
+
return Object.freeze({ type: source.type, ...minimum2 === void 0 ? {} : { minimum: minimum2 }, ...maximum === void 0 ? {} : { maximum }, ...annotation });
|
|
159
|
+
}
|
|
160
|
+
case "boolean":
|
|
161
|
+
case "null":
|
|
162
|
+
keys(source, ["type", "description"], path);
|
|
163
|
+
return Object.freeze({ type: source.type, ...annotation });
|
|
164
|
+
default:
|
|
165
|
+
invalid("Schema node type is unsupported.", [...path, "type"]);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const schema = node(input, 1, [], true);
|
|
169
|
+
if (!("type" in schema) || schema.type !== "object") invalid("The output schema root must be an object.", []);
|
|
170
|
+
const minimum = minimumValueSize(schema);
|
|
171
|
+
if (minimum.bytes > AGENT_OUTPUT_VALUE_BYTES_LIMIT || minimum.nodes > AGENT_OUTPUT_VALUE_NODES_LIMIT || minimum.depth > AGENT_OUTPUT_VALUE_DEPTH_LIMIT) {
|
|
172
|
+
invalid("Schema cannot produce a value within the profile capacity limits.", []);
|
|
173
|
+
}
|
|
174
|
+
if (minimum.bytes > maxOutputBytes) {
|
|
175
|
+
invalid("Schema cannot produce a value within the configured output byte limit.", []);
|
|
176
|
+
}
|
|
177
|
+
return schema;
|
|
178
|
+
}
|
|
179
|
+
function decimalExponent(value) {
|
|
180
|
+
const notation = value.toExponential();
|
|
181
|
+
return Number(notation.slice(notation.indexOf("e") + 1));
|
|
182
|
+
}
|
|
183
|
+
function minimumNumberBytes(schema) {
|
|
184
|
+
const lower = schema.minimum ?? -Number.MAX_VALUE;
|
|
185
|
+
const upper = schema.maximum ?? Number.MAX_VALUE;
|
|
186
|
+
const minimum = schema.type === "integer" ? Math.ceil(lower) : lower;
|
|
187
|
+
const maximum = schema.type === "integer" ? Math.floor(upper) : upper;
|
|
188
|
+
if (minimum === maximum) return JSON.stringify(minimum).length;
|
|
189
|
+
if (minimum <= 0 && maximum >= 0) return 1;
|
|
190
|
+
const negative = maximum < 0;
|
|
191
|
+
const absoluteMinimum = negative ? -maximum : minimum;
|
|
192
|
+
const absoluteMaximum = negative ? -minimum : maximum;
|
|
193
|
+
let bytes = Infinity;
|
|
194
|
+
const maximumExponent = decimalExponent(absoluteMaximum);
|
|
195
|
+
for (let exponent = decimalExponent(absoluteMinimum); exponent <= maximumExponent; exponent += 1) {
|
|
196
|
+
let bandBytes;
|
|
197
|
+
if (exponent < -6 || exponent >= 21) {
|
|
198
|
+
bandBytes = 3 + String(Math.abs(exponent)).length;
|
|
199
|
+
} else if (exponent < 0) {
|
|
200
|
+
bandBytes = 2 - exponent;
|
|
201
|
+
} else {
|
|
202
|
+
const firstInteger = Math.ceil(Math.max(absoluteMinimum, Number(`1e${exponent}`)));
|
|
203
|
+
const containsInteger = firstInteger <= absoluteMaximum && firstInteger < Number(`1e${exponent + 1}`);
|
|
204
|
+
bandBytes = exponent + 1 + (containsInteger ? 0 : 2);
|
|
205
|
+
}
|
|
206
|
+
bytes = Math.min(bytes, bandBytes);
|
|
207
|
+
}
|
|
208
|
+
return bytes + (negative ? 1 : 0);
|
|
209
|
+
}
|
|
210
|
+
function minimumValueSize(schema) {
|
|
211
|
+
if ("anyOf" in schema) {
|
|
212
|
+
const nonNull = minimumValueSize(schema.anyOf[0]);
|
|
213
|
+
return { bytes: Math.min(4, nonNull.bytes), nodes: 1, depth: 1 };
|
|
214
|
+
}
|
|
215
|
+
switch (schema.type) {
|
|
216
|
+
case "object": {
|
|
217
|
+
const entries = Object.entries(schema.properties);
|
|
218
|
+
let bytes = 2 + Math.max(0, entries.length - 1);
|
|
219
|
+
let nodes = 1;
|
|
220
|
+
let depth = 1;
|
|
221
|
+
for (const [name, child] of entries) {
|
|
222
|
+
const minimum = minimumValueSize(child);
|
|
223
|
+
bytes += serializedStringBytes(name, AGENT_OUTPUT_SCHEMA_BYTES_LIMIT) + 1 + minimum.bytes;
|
|
224
|
+
nodes += minimum.nodes;
|
|
225
|
+
depth = Math.max(depth, 1 + minimum.depth);
|
|
226
|
+
}
|
|
227
|
+
return { bytes, nodes, depth };
|
|
228
|
+
}
|
|
229
|
+
case "array": {
|
|
230
|
+
const count = schema.minItems ?? 0;
|
|
231
|
+
const child = minimumValueSize(schema.items);
|
|
232
|
+
return { bytes: 2 + Math.max(0, count - 1) + count * child.bytes, nodes: 1 + count * child.nodes, depth: count === 0 ? 1 : 1 + child.depth };
|
|
233
|
+
}
|
|
234
|
+
case "string":
|
|
235
|
+
return { bytes: schema.enum ? Math.min(...schema.enum.map((value) => serializedStringBytes(value, AGENT_OUTPUT_SCHEMA_BYTES_LIMIT))) : 2 + (schema.minLength ?? 0), nodes: 1, depth: 1 };
|
|
236
|
+
case "boolean":
|
|
237
|
+
case "null":
|
|
238
|
+
return { bytes: 4, nodes: 1, depth: 1 };
|
|
239
|
+
case "integer":
|
|
240
|
+
case "number":
|
|
241
|
+
return { bytes: minimumNumberBytes(schema), nodes: 1, depth: 1 };
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
export {
|
|
245
|
+
StructuredOutputSchemaError,
|
|
246
|
+
admitOutputSchema
|
|
247
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { AgentJsonObject, ValidationIssue } from '../foundation/types.js';
|
|
2
|
+
import type { AGENT_OUTPUT_SCHEMA_DIALECT, AGENT_OUTPUT_SCHEMA_PROFILE } from './constants.js';
|
|
3
|
+
interface AgentOutputSchemaDescription {
|
|
4
|
+
readonly description?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface AgentOutputObjectSchema extends AgentOutputSchemaDescription {
|
|
7
|
+
readonly type: 'object';
|
|
8
|
+
readonly properties: Readonly<Record<string, AgentOutputSchemaNode>>;
|
|
9
|
+
readonly required: readonly string[];
|
|
10
|
+
readonly additionalProperties: false;
|
|
11
|
+
}
|
|
12
|
+
export interface AgentOutputSchema extends AgentOutputObjectSchema {
|
|
13
|
+
readonly $schema?: typeof AGENT_OUTPUT_SCHEMA_DIALECT;
|
|
14
|
+
}
|
|
15
|
+
export interface AgentOutputArraySchema extends AgentOutputSchemaDescription {
|
|
16
|
+
readonly type: 'array';
|
|
17
|
+
readonly items: AgentOutputSchemaNode;
|
|
18
|
+
readonly minItems?: number;
|
|
19
|
+
readonly maxItems?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface AgentOutputStringSchema extends AgentOutputSchemaDescription {
|
|
22
|
+
readonly type: 'string';
|
|
23
|
+
readonly enum?: readonly [string, ...string[]];
|
|
24
|
+
readonly minLength?: number;
|
|
25
|
+
readonly maxLength?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface AgentOutputNumberSchema extends AgentOutputSchemaDescription {
|
|
28
|
+
readonly type: 'integer' | 'number';
|
|
29
|
+
readonly minimum?: number;
|
|
30
|
+
readonly maximum?: number;
|
|
31
|
+
}
|
|
32
|
+
export interface AgentOutputBooleanSchema extends AgentOutputSchemaDescription {
|
|
33
|
+
readonly type: 'boolean';
|
|
34
|
+
}
|
|
35
|
+
export interface AgentOutputNullSchema extends AgentOutputSchemaDescription {
|
|
36
|
+
readonly type: 'null';
|
|
37
|
+
}
|
|
38
|
+
export type AgentOutputNonNullSchema = AgentOutputObjectSchema | AgentOutputArraySchema | AgentOutputStringSchema | AgentOutputNumberSchema | AgentOutputBooleanSchema;
|
|
39
|
+
export interface AgentOutputNullableSchema extends AgentOutputSchemaDescription {
|
|
40
|
+
readonly anyOf: readonly [AgentOutputNonNullSchema, AgentOutputNullSchema];
|
|
41
|
+
}
|
|
42
|
+
export type AgentOutputSchemaNode = AgentOutputNonNullSchema | AgentOutputNullSchema | AgentOutputNullableSchema;
|
|
43
|
+
export type AgentStructuredOutputCapability = Readonly<{
|
|
44
|
+
kind: 'unsupported';
|
|
45
|
+
}> | Readonly<{
|
|
46
|
+
kind: 'supported';
|
|
47
|
+
mechanism: 'native';
|
|
48
|
+
schemaProfile: typeof AGENT_OUTPUT_SCHEMA_PROFILE;
|
|
49
|
+
scope: 'turn' | 'session';
|
|
50
|
+
maxSchemaBytes: number;
|
|
51
|
+
maxOutputBytes: number;
|
|
52
|
+
resume: false;
|
|
53
|
+
branch: false;
|
|
54
|
+
}>;
|
|
55
|
+
export type AgentStructuredOutputRequest = Readonly<{
|
|
56
|
+
kind: 'json_schema';
|
|
57
|
+
schema: AgentOutputSchema;
|
|
58
|
+
}>;
|
|
59
|
+
export type AgentStructuredOutputUnavailableReason = 'refused' | 'incomplete' | 'missing_output' | 'invalid_json' | 'schema_mismatch' | 'output_limit_exceeded' | 'native_retries_exhausted' | 'provider_error';
|
|
60
|
+
export type AgentStructuredOutputNonJsonResult = Readonly<{
|
|
61
|
+
kind: 'not_requested';
|
|
62
|
+
}> | Readonly<{
|
|
63
|
+
kind: 'unavailable';
|
|
64
|
+
reason: 'schema_mismatch';
|
|
65
|
+
issues?: readonly ValidationIssue[];
|
|
66
|
+
}> | Readonly<{
|
|
67
|
+
kind: 'unavailable';
|
|
68
|
+
reason: Exclude<AgentStructuredOutputUnavailableReason, 'schema_mismatch'>;
|
|
69
|
+
}>;
|
|
70
|
+
export type AgentStructuredOutputResult = AgentStructuredOutputNonJsonResult | Readonly<{
|
|
71
|
+
kind: 'json';
|
|
72
|
+
value: AgentJsonObject;
|
|
73
|
+
}>;
|
|
74
|
+
export {};
|
|
75
|
+
//# sourceMappingURL=types.d.ts.map
|
|
File without changes
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { AgentJsonObject, AgentProtocolParseResult } from '../foundation/types.js';
|
|
2
|
+
import { type AgentOutputLimits } from './parsers.js';
|
|
3
|
+
import type { AgentOutputSchema } from './types.js';
|
|
4
|
+
export declare function validateAgentOutputValue(schema: AgentOutputSchema, candidate: unknown, limits?: AgentOutputLimits): AgentProtocolParseResult<AgentJsonObject>;
|
|
5
|
+
//# sourceMappingURL=values.d.ts.map
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { codePointLength, isJsonObject, snapshotStructuredOutputJson } from "./boundedJson.js";
|
|
2
|
+
import {
|
|
3
|
+
AGENT_OUTPUT_VALUE_COLLECTION_LIMIT,
|
|
4
|
+
AGENT_OUTPUT_VALUE_DEPTH_LIMIT,
|
|
5
|
+
AGENT_OUTPUT_VALUE_NODES_LIMIT
|
|
6
|
+
} from "./constants.js";
|
|
7
|
+
import { StructuredOutputIssues } from "./issues.js";
|
|
8
|
+
import { parseOutputByteLimit, trustedOutputSchema } from "./parsers.js";
|
|
9
|
+
function isJsonArray(value) {
|
|
10
|
+
return Array.isArray(value);
|
|
11
|
+
}
|
|
12
|
+
function validateAgentOutputValue(schema, candidate, limits) {
|
|
13
|
+
const parsedLimit = parseOutputByteLimit(limits);
|
|
14
|
+
if (!parsedLimit.success) return parsedLimit;
|
|
15
|
+
const admitted = trustedOutputSchema(schema);
|
|
16
|
+
if (!admitted.success) return admitted;
|
|
17
|
+
const snapshot = snapshotStructuredOutputJson(candidate, {
|
|
18
|
+
maxBytes: parsedLimit.data,
|
|
19
|
+
maxDepth: AGENT_OUTPUT_VALUE_DEPTH_LIMIT,
|
|
20
|
+
maxNodes: AGENT_OUTPUT_VALUE_NODES_LIMIT,
|
|
21
|
+
maxCollectionLength: AGENT_OUTPUT_VALUE_COLLECTION_LIMIT
|
|
22
|
+
});
|
|
23
|
+
if (!snapshot.success) return snapshot;
|
|
24
|
+
const issues = new StructuredOutputIssues();
|
|
25
|
+
function matches(node, value, path) {
|
|
26
|
+
if (issues.full) return;
|
|
27
|
+
if ("anyOf" in node) {
|
|
28
|
+
if (value !== null) matches(node.anyOf[0], value, path);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
switch (node.type) {
|
|
32
|
+
case "object":
|
|
33
|
+
if (!isJsonObject(value)) break;
|
|
34
|
+
for (const key of Object.keys(value)) {
|
|
35
|
+
if (!Object.hasOwn(node.properties, key)) issues.add("schema_mismatch", "Object contains an undeclared property.", [...path, key]);
|
|
36
|
+
}
|
|
37
|
+
for (const [key, childSchema] of Object.entries(node.properties)) {
|
|
38
|
+
const child = value[key];
|
|
39
|
+
if (child === void 0) issues.add("schema_mismatch", "Object is missing a required property.", [...path, key]);
|
|
40
|
+
else matches(childSchema, child, [...path, key]);
|
|
41
|
+
if (issues.full) return;
|
|
42
|
+
}
|
|
43
|
+
return;
|
|
44
|
+
case "array":
|
|
45
|
+
if (!isJsonArray(value)) break;
|
|
46
|
+
if (node.minItems !== void 0 && value.length < node.minItems || node.maxItems !== void 0 && value.length > node.maxItems) {
|
|
47
|
+
issues.add("schema_mismatch", "Array length is outside the declared bounds.", path);
|
|
48
|
+
}
|
|
49
|
+
for (const [index, child] of value.entries()) {
|
|
50
|
+
matches(node.items, child, [...path, index]);
|
|
51
|
+
if (issues.full) return;
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
case "string": {
|
|
55
|
+
if (typeof value !== "string") break;
|
|
56
|
+
const length = codePointLength(value);
|
|
57
|
+
if (node.minLength !== void 0 && length < node.minLength || node.maxLength !== void 0 && length > node.maxLength) {
|
|
58
|
+
issues.add("schema_mismatch", "String code-point length is outside the declared bounds.", path);
|
|
59
|
+
}
|
|
60
|
+
if (node.enum && !node.enum.includes(value)) issues.add("schema_mismatch", "String is not one of the declared enum values.", path);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
case "integer":
|
|
64
|
+
case "number":
|
|
65
|
+
if (typeof value !== "number" || node.type === "integer" && !Number.isInteger(value)) break;
|
|
66
|
+
if (node.minimum !== void 0 && value < node.minimum || node.maximum !== void 0 && value > node.maximum) {
|
|
67
|
+
issues.add("schema_mismatch", "Number is outside the declared inclusive bounds.", path);
|
|
68
|
+
}
|
|
69
|
+
return;
|
|
70
|
+
case "boolean":
|
|
71
|
+
if (typeof value === "boolean") return;
|
|
72
|
+
break;
|
|
73
|
+
case "null":
|
|
74
|
+
if (value === null) return;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
issues.add("schema_mismatch", "Value does not have the declared JSON type.", path);
|
|
78
|
+
}
|
|
79
|
+
matches(admitted.data, snapshot.data, []);
|
|
80
|
+
if (issues.issues.length > 0) return { success: false, issues: issues.issues };
|
|
81
|
+
if (!isJsonObject(snapshot.data)) {
|
|
82
|
+
issues.add("schema_mismatch", "Output must be a JSON object.");
|
|
83
|
+
return { success: false, issues: issues.issues };
|
|
84
|
+
}
|
|
85
|
+
return { success: true, data: snapshot.data };
|
|
86
|
+
}
|
|
87
|
+
export {
|
|
88
|
+
validateAgentOutputValue
|
|
89
|
+
};
|
package/dist/turns/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AgentError, AgentEnvironmentId, AgentEffectiveContentId, AgentIsoDateTime, AgentItemId, AgentTurnId } from '../foundation/index.js';
|
|
2
|
+
import type { AgentStructuredOutputNonJsonResult, AgentStructuredOutputRequest, AgentStructuredOutputResult } from '../structuredOutput/types.js';
|
|
2
3
|
export interface AgentTextInputPart {
|
|
3
4
|
readonly type: 'text';
|
|
4
5
|
readonly text: string;
|
|
@@ -50,6 +51,7 @@ export interface AgentTurnRunInput extends AgentTurnInputContent {
|
|
|
50
51
|
readonly turnId: AgentTurnId;
|
|
51
52
|
readonly interactionMode: AgentTurnInteractionMode;
|
|
52
53
|
readonly deadlineAt?: AgentIsoDateTime;
|
|
54
|
+
readonly output?: AgentStructuredOutputRequest;
|
|
53
55
|
}
|
|
54
56
|
export type AgentTurnInterruptionReason = 'user_requested' | 'timeout' | 'shutdown' | 'superseded' | 'other';
|
|
55
57
|
export interface AgentTurnInterruptionInput {
|
|
@@ -247,10 +249,21 @@ export interface AgentDiffSummary {
|
|
|
247
249
|
readonly malformed?: boolean;
|
|
248
250
|
readonly truncated?: boolean;
|
|
249
251
|
}
|
|
250
|
-
export
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
252
|
+
export type AgentTurnCompletedPayload = Readonly<{
|
|
253
|
+
outcome: 'completed';
|
|
254
|
+
structuredOutput: AgentStructuredOutputResult;
|
|
255
|
+
reason?: string;
|
|
256
|
+
error?: never;
|
|
257
|
+
}> | Readonly<{
|
|
258
|
+
outcome: 'failed';
|
|
259
|
+
structuredOutput: AgentStructuredOutputNonJsonResult;
|
|
260
|
+
reason?: string;
|
|
261
|
+
error: AgentError;
|
|
262
|
+
}> | Readonly<{
|
|
263
|
+
outcome: 'canceled' | 'expired';
|
|
264
|
+
structuredOutput: AgentStructuredOutputNonJsonResult;
|
|
265
|
+
reason?: string;
|
|
266
|
+
error?: never;
|
|
267
|
+
}>;
|
|
255
268
|
export {};
|
|
256
269
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -139,7 +139,7 @@ export declare const AgentOperationInputCapabilitySchema: z.ZodReadonly<z.ZodObj
|
|
|
139
139
|
}, z.core.$strict>>], "kind">;
|
|
140
140
|
}, z.core.$strict>>;
|
|
141
141
|
export declare const AgentCapabilitiesPortableSchema: z.ZodReadonly<z.ZodObject<{
|
|
142
|
-
protocolVersion: z.ZodLiteral<
|
|
142
|
+
protocolVersion: z.ZodLiteral<13>;
|
|
143
143
|
providerKey: z.ZodType<import("../index.js").AgentProviderKey, unknown, z.core.$ZodTypeInternals<import("../index.js").AgentProviderKey, unknown>>;
|
|
144
144
|
sessions: z.ZodReadonly<z.ZodObject<{
|
|
145
145
|
create: z.ZodLiteral<true>;
|
|
@@ -156,6 +156,7 @@ export declare const AgentCapabilitiesPortableSchema: z.ZodReadonly<z.ZodObject<
|
|
|
156
156
|
plan: "plan";
|
|
157
157
|
}>>>;
|
|
158
158
|
interrupt: z.ZodBoolean;
|
|
159
|
+
structuredOutput: z.ZodType<import("../index.js").AgentStructuredOutputCapability, unknown, z.core.$ZodTypeInternals<import("../index.js").AgentStructuredOutputCapability, unknown>>;
|
|
159
160
|
steer: z.ZodDiscriminatedUnion<[z.ZodReadonly<z.ZodObject<{
|
|
160
161
|
kind: z.ZodLiteral<"unsupported">;
|
|
161
162
|
}, z.core.$strict>>, z.ZodReadonly<z.ZodObject<{
|
|
@@ -396,10 +397,10 @@ export declare const AgentCapabilitiesPortableSchema: z.ZodReadonly<z.ZodObject<
|
|
|
396
397
|
}>>>;
|
|
397
398
|
fieldKinds: z.ZodReadonly<z.ZodArray<z.ZodEnum<{
|
|
398
399
|
boolean: "boolean";
|
|
400
|
+
integer: "integer";
|
|
399
401
|
single_select: "single_select";
|
|
400
402
|
text: "text";
|
|
401
403
|
multi_select: "multi_select";
|
|
402
|
-
integer: "integer";
|
|
403
404
|
}>>>;
|
|
404
405
|
executionModes: z.ZodReadonly<z.ZodArray<z.ZodEnum<{
|
|
405
406
|
immediate: "immediate";
|
package/dist/zod/capabilities.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod/v4";
|
|
2
|
+
import { AgentStructuredOutputCapabilitySchema } from "./structuredOutput.js";
|
|
2
3
|
import { AgentEnvironmentCapabilitySchema } from "./environment.js";
|
|
3
4
|
import { AGENT_CONTENT_REFERENCES_MAX_LENGTH } from "../turns/types.js";
|
|
4
5
|
import {
|
|
@@ -283,6 +284,7 @@ const AgentCapabilitiesPortableSchema = z.object({
|
|
|
283
284
|
turns: z.object({
|
|
284
285
|
interactionModes: z.array(z.enum(AGENT_TURN_INTERACTION_MODES)).min(1).max(AGENT_TURN_INTERACTION_MODES.length).meta({ uniqueItems: true }).readonly(),
|
|
285
286
|
interrupt: z.boolean(),
|
|
287
|
+
structuredOutput: AgentStructuredOutputCapabilitySchema,
|
|
286
288
|
steer: z.discriminatedUnion("kind", [
|
|
287
289
|
z.object({ kind: z.literal("unsupported") }).strict().readonly(),
|
|
288
290
|
z.object({
|