@tangle-network/agent-interface 2.5.0 → 2.6.1

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.
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import type { AgentCandidateLineage } from "./agent-candidate.js";
2
3
  export declare const agentCandidateKnowledgeSchema: z.ZodObject<{
3
4
  candidate: z.ZodObject<{
4
5
  kind: z.ZodLiteral<"knowledge-improvement-candidate">;
@@ -124,9 +125,19 @@ export declare const agentCandidateMemoryPolicySchema: z.ZodDiscriminatedUnion<[
124
125
  byteLength: z.ZodNumber;
125
126
  }, z.core.$strict>>;
126
127
  }, z.core.$strict>], "mode">;
128
+ /**
129
+ * Sources whose candidate was PRODUCED from a parent rather than supplied whole.
130
+ *
131
+ * One list, read by the lineage schema and by every experiment schema that gates on it. Three
132
+ * call sites branched on `optimizer || compound` independently, so adding a fourth generated
133
+ * source silently exempted it from the "name your baseline" rule in two of them.
134
+ */
135
+ export declare const generatedCandidateSources: readonly ["optimizer", "compound", "frontier-author"];
136
+ export declare function isGeneratedCandidateSource(source: AgentCandidateLineage["source"]): boolean;
127
137
  export declare const agentCandidateLineageSchema: z.ZodObject<{
128
138
  source: z.ZodEnum<{
129
139
  compound: "compound";
140
+ "frontier-author": "frontier-author";
130
141
  human: "human";
131
142
  import: "import";
132
143
  optimizer: "optimizer";
@@ -39,9 +39,30 @@ export const agentCandidateMemoryPolicySchema = z.discriminatedUnion("mode", [
39
39
  })
40
40
  .strict(),
41
41
  ]);
42
+ /**
43
+ * Sources whose candidate was PRODUCED from a parent rather than supplied whole.
44
+ *
45
+ * One list, read by the lineage schema and by every experiment schema that gates on it. Three
46
+ * call sites branched on `optimizer || compound` independently, so adding a fourth generated
47
+ * source silently exempted it from the "name your baseline" rule in two of them.
48
+ */
49
+ export const generatedCandidateSources = [
50
+ "optimizer",
51
+ "compound",
52
+ "frontier-author",
53
+ ];
54
+ export function isGeneratedCandidateSource(source) {
55
+ return generatedCandidateSources.includes(source);
56
+ }
42
57
  export const agentCandidateLineageSchema = z
43
58
  .object({
44
- source: z.enum(["optimizer", "human", "import", "compound"]),
59
+ source: z.enum([
60
+ "optimizer",
61
+ "human",
62
+ "import",
63
+ "compound",
64
+ "frontier-author",
65
+ ]),
45
66
  parentDigests: z.array(sha256DigestSchema).optional(),
46
67
  runIds: z.array(z.string().min(1)).optional(),
47
68
  profileDiffIds: z.array(z.string().min(1)).optional(),
@@ -62,7 +83,9 @@ export const agentCandidateLineageSchema = z
62
83
  message: "compound candidates must name at least two distinct parents",
63
84
  });
64
85
  }
65
- if (lineage.source === "optimizer" || lineage.source === "compound") {
86
+ // Every generated lineage names what it came from and the run that produced
87
+ // it, whoever generated it.
88
+ if (isGeneratedCandidateSource(lineage.source)) {
66
89
  if ((lineage.parentDigests?.length ?? 0) === 0) {
67
90
  ctx.addIssue({
68
91
  code: "custom",
@@ -77,6 +100,13 @@ export const agentCandidateLineageSchema = z
77
100
  message: "generated candidates must name their producing run",
78
101
  });
79
102
  }
103
+ }
104
+ // A development split exists only when an offline search produced the
105
+ // candidate. An agent that authors a profile inside a run has no held-out
106
+ // set to pin, so requiring one would force a fabricated digest into the
107
+ // evidence record. This branch is deliberately NOT the generated-source
108
+ // list above.
109
+ if (lineage.source === "optimizer" || lineage.source === "compound") {
80
110
  if (lineage.developmentSplitDigest === undefined) {
81
111
  ctx.addIssue({
82
112
  code: "custom",
@@ -1680,6 +1680,7 @@ export declare const agentCandidateExperimentSchema: z.ZodObject<{
1680
1680
  candidateLineage: z.ZodObject<{
1681
1681
  source: z.ZodEnum<{
1682
1682
  compound: "compound";
1683
+ "frontier-author": "frontier-author";
1683
1684
  human: "human";
1684
1685
  import: "import";
1685
1686
  optimizer: "optimizer";
@@ -5277,6 +5278,7 @@ export declare const agentImprovementMeasuredComparisonSchema: z.ZodObject<{
5277
5278
  candidateLineage: z.ZodObject<{
5278
5279
  source: z.ZodEnum<{
5279
5280
  compound: "compound";
5281
+ "frontier-author": "frontier-author";
5280
5282
  human: "human";
5281
5283
  import: "import";
5282
5284
  optimizer: "optimizer";
@@ -10304,6 +10306,7 @@ export declare const agentImprovementProposalSchema: z.ZodObject<{
10304
10306
  candidateLineage: z.ZodObject<{
10305
10307
  source: z.ZodEnum<{
10306
10308
  compound: "compound";
10309
+ "frontier-author": "frontier-author";
10307
10310
  human: "human";
10308
10311
  import: "import";
10309
10312
  optimizer: "optimizer";
@@ -13666,6 +13669,7 @@ export declare const agentImprovementProposalSchema: z.ZodObject<{
13666
13669
  candidateLineage: z.ZodObject<{
13667
13670
  source: z.ZodEnum<{
13668
13671
  compound: "compound";
13672
+ "frontier-author": "frontier-author";
13669
13673
  human: "human";
13670
13674
  import: "import";
13671
13675
  optimizer: "optimizer";
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { AGENT_IMPROVEMENT_SURFACES } from "./agent-candidate.js";
3
3
  import { agentCandidateBundleSchema } from "./agent-candidate-schema.js";
4
- import { agentCandidateLineageSchema } from "./agent-candidate-lineage-schema.js";
4
+ import { agentCandidateLineageSchema, isGeneratedCandidateSource, } from "./agent-candidate-lineage-schema.js";
5
5
  import { agentCandidateBenchmarkSuiteInputsSchema } from "./agent-candidate-task-schema.js";
6
6
  import { canonicalCandidateDigest, isCanonicalJsonValue, sha256DigestSchema, } from "./agent-candidate-schema-common.js";
7
7
  import { refineAgentExecutionWithinLimits } from "./agent-execution-limits.js";
@@ -23,7 +23,7 @@ export const agentCandidateExperimentSchema = z
23
23
  .strict()
24
24
  .superRefine((experiment, ctx) => {
25
25
  const source = experiment.candidateLineage.source;
26
- if ((source === "optimizer" || source === "compound") &&
26
+ if (isGeneratedCandidateSource(source) &&
27
27
  !experiment.candidateLineage.parentDigests?.includes(experiment.baseline.digest)) {
28
28
  ctx.addIssue({
29
29
  code: "custom",
@@ -288,7 +288,20 @@ export interface AgentCandidateFixedSpend {
288
288
  }
289
289
  /** Evidence and ancestry that produced the immutable candidate. */
290
290
  export interface AgentCandidateLineage {
291
- source: "optimizer" | "human" | "import" | "compound";
291
+ /**
292
+ * Who produced this candidate.
293
+ *
294
+ * `frontier-author` is an agent that wrote another agent's profile — the same
295
+ * member {@link AgentProfileDiff}`.source.kind` already carries, so the two
296
+ * enums name one actor with one word. It covers a supervising agent authoring
297
+ * a child's full `AgentProfile` from inside a run, which `spawn_worker`
298
+ * exposes and a `driver` role promotes to a sub-supervisor.
299
+ *
300
+ * It carries `optimizer`'s parent and run requirements and not its
301
+ * `developmentSplitDigest`: there is no held-out split and no offline search
302
+ * behind a profile an agent wrote while working.
303
+ */
304
+ source: "optimizer" | "human" | "import" | "compound" | "frontier-author";
292
305
  parentDigests?: Sha256Digest[];
293
306
  runIds?: string[];
294
307
  profileDiffIds?: string[];
@@ -236,6 +236,7 @@ export declare const agentProfileImprovementExperimentSchema: z.ZodObject<{
236
236
  candidateLineage: z.ZodObject<{
237
237
  source: z.ZodEnum<{
238
238
  compound: "compound";
239
+ "frontier-author": "frontier-author";
239
240
  human: "human";
240
241
  import: "import";
241
242
  optimizer: "optimizer";
@@ -768,6 +769,7 @@ export declare const agentProfileImprovementMeasuredComparisonSchema: z.ZodObjec
768
769
  candidateLineage: z.ZodObject<{
769
770
  source: z.ZodEnum<{
770
771
  compound: "compound";
772
+ "frontier-author": "frontier-author";
771
773
  human: "human";
772
774
  import: "import";
773
775
  optimizer: "optimizer";
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { changedAgentProfileAxes } from "./profile-diff.js";
3
- import { agentCandidateLineageSchema } from "./agent-candidate-lineage-schema.js";
3
+ import { agentCandidateLineageSchema, isGeneratedCandidateSource, } from "./agent-candidate-lineage-schema.js";
4
4
  import { canonicalCandidateDigest, isCanonicalJsonValue, omitTopLevelDigest, sha256DigestSchema, } from "./agent-candidate-schema-common.js";
5
5
  import { refineAgentExecutionWithinLimits } from "./agent-execution-limits.js";
6
6
  import { agentCandidateBenchmarkGraderIdentitySchema, agentCandidateExecutionLimitsSchema, agentCandidateResolvedModelSchema, } from "./agent-candidate-execution-plan-schema.js";
@@ -189,7 +189,7 @@ export const agentProfileImprovementExperimentSchema = z
189
189
  });
190
190
  }
191
191
  const source = experiment.candidateLineage.source;
192
- if ((source === "optimizer" || source === "compound") &&
192
+ if (isGeneratedCandidateSource(source) &&
193
193
  !experiment.candidateLineage.parentDigests?.includes(experiment.baseline.stateDigest)) {
194
194
  ctx.addIssue({
195
195
  code: "custom",
@@ -18,10 +18,23 @@ export declare const boundedIdentifierSchema: z.ZodString;
18
18
  * checked before canonical serialization.
19
19
  */
20
20
  export declare function isBoundedJsonValue(value: unknown): boolean;
21
+ /**
22
+ * Validate provider event and terminal content. Unlike ordinary metadata,
23
+ * content may contain a single large transcript or tool result. It remains
24
+ * finite, plain JSON with the normal structural limits, and its complete JSON
25
+ * representation is capped exactly by UTF-8 bytes.
26
+ */
27
+ export declare function isBoundedEventContentJson(value: unknown, { omitUndefinedObjectFields }?: {
28
+ omitUndefinedObjectFields?: boolean;
29
+ }): boolean;
21
30
  /** Validate digest input while matching JSON's omission of undefined object fields. */
22
31
  export declare function isBoundedJsonMaterial(value: unknown): boolean;
23
32
  export declare const boundedJsonSchema: z.ZodCustom<unknown, unknown>;
24
33
  export declare const boundedJsonRecordSchema: z.ZodCustom<Record<string, unknown>, Record<string, unknown>>;
34
+ /** One provider event payload or terminal response, bounded as serialized UTF-8 JSON. */
35
+ export declare const boundedEventContentJsonSchema: z.ZodCustom<unknown, unknown>;
36
+ export declare const boundedEventContentRecordSchema: z.ZodCustom<Record<string, unknown>, Record<string, unknown>>;
37
+ export declare const boundedEventContentStringSchema: z.ZodCustom<string, string>;
25
38
  export declare function assertBoundedJson(value: unknown): void;
26
39
  export declare function assertBoundedSerializedJson(value: string): void;
27
40
  /** Copy arbitrary metadata into a map that cannot inherit prototype keys. */
@@ -84,6 +84,162 @@ export function isBoundedJsonValue(value) {
84
84
  }
85
85
  return true;
86
86
  }
87
+ /** Exact serialized JSON UTF-8 byte count for one string scalar. */
88
+ function serializedJsonStringBytes(value) {
89
+ let bytes = 2; // Opening and closing quotes.
90
+ for (let index = 0; index < value.length; index += 1) {
91
+ const code = value.charCodeAt(index);
92
+ if (code === 0x22 || code === 0x5c || code === 0x08 || code === 0x0c || code === 0x0a || code === 0x0d || code === 0x09) {
93
+ bytes += 2;
94
+ }
95
+ else if (code < 0x20) {
96
+ bytes += 6;
97
+ }
98
+ else if (code >= 0xd800 && code <= 0xdbff && index + 1 < value.length) {
99
+ const next = value.charCodeAt(index + 1);
100
+ if (next >= 0xdc00 && next <= 0xdfff) {
101
+ bytes += 4;
102
+ index += 1;
103
+ }
104
+ else {
105
+ bytes += 6;
106
+ }
107
+ }
108
+ else if (code >= 0xd800 && code <= 0xdfff) {
109
+ bytes += 6;
110
+ }
111
+ else if (code < 0x80) {
112
+ bytes += 1;
113
+ }
114
+ else if (code < 0x800) {
115
+ bytes += 2;
116
+ }
117
+ else {
118
+ bytes += 3;
119
+ }
120
+ if (bytes > CONTRACT_MAX_JSON_BYTES)
121
+ return bytes;
122
+ }
123
+ return bytes;
124
+ }
125
+ /**
126
+ * Validate provider event and terminal content. Unlike ordinary metadata,
127
+ * content may contain a single large transcript or tool result. It remains
128
+ * finite, plain JSON with the normal structural limits, and its complete JSON
129
+ * representation is capped exactly by UTF-8 bytes.
130
+ */
131
+ export function isBoundedEventContentJson(value, { omitUndefinedObjectFields = false } = {}) {
132
+ const pending = [
133
+ { value, depth: 0 },
134
+ ];
135
+ const ancestors = new Set();
136
+ let nodes = 0;
137
+ let bytes = 0;
138
+ const addBytes = (additional) => {
139
+ bytes += additional;
140
+ return bytes <= CONTRACT_MAX_JSON_BYTES;
141
+ };
142
+ while (pending.length > 0) {
143
+ const item = pending.pop();
144
+ if (!item)
145
+ continue;
146
+ const current = item.value;
147
+ if (current === undefined && item.omitUndefined === true)
148
+ continue;
149
+ nodes += 1;
150
+ if (nodes > CONTRACT_MAX_JSON_NODES)
151
+ return false;
152
+ if (item.leave) {
153
+ ancestors.delete(current);
154
+ continue;
155
+ }
156
+ if (current === null) {
157
+ if (!addBytes(4))
158
+ return false;
159
+ continue;
160
+ }
161
+ if (typeof current === "boolean") {
162
+ if (!addBytes(current ? 4 : 5))
163
+ return false;
164
+ continue;
165
+ }
166
+ if (typeof current === "string") {
167
+ if (!addBytes(serializedJsonStringBytes(current)))
168
+ return false;
169
+ continue;
170
+ }
171
+ if (typeof current === "number") {
172
+ if (!Number.isFinite(current))
173
+ return false;
174
+ if (!addBytes(JSON.stringify(current).length))
175
+ return false;
176
+ continue;
177
+ }
178
+ if (typeof current !== "object" || item.depth >= CONTRACT_MAX_JSON_DEPTH) {
179
+ return false;
180
+ }
181
+ if (ancestors.has(current))
182
+ return false;
183
+ ancestors.add(current);
184
+ pending.push({ value: current, depth: item.depth, leave: true });
185
+ if (Array.isArray(current)) {
186
+ if (current.length > CONTRACT_MAX_ARRAY_LENGTH)
187
+ return false;
188
+ if (!addBytes(2 + Math.max(current.length - 1, 0)))
189
+ return false;
190
+ const prototype = Object.getPrototypeOf(current);
191
+ if (prototype !== Array.prototype && prototype !== null)
192
+ return false;
193
+ const keys = Reflect.ownKeys(current);
194
+ const entryKeys = keys.filter((key) => key !== "length");
195
+ if (entryKeys.length !== current.length)
196
+ return false;
197
+ if (entryKeys.some((key) => {
198
+ if (typeof key !== "string" || !/^(?:0|[1-9][0-9]*)$/u.test(key))
199
+ return true;
200
+ const index = Number(key);
201
+ return !Number.isSafeInteger(index) || index < 0 || index >= current.length || index >= 4_294_967_295;
202
+ })) {
203
+ return false;
204
+ }
205
+ for (const key of entryKeys) {
206
+ const descriptor = Object.getOwnPropertyDescriptor(current, key);
207
+ if (descriptor === undefined || !descriptor.enumerable || !("value" in descriptor))
208
+ return false;
209
+ pending.push({ value: descriptor.value, depth: item.depth + 1 });
210
+ }
211
+ continue;
212
+ }
213
+ const prototype = Object.getPrototypeOf(current);
214
+ if (prototype !== Object.prototype && prototype !== null)
215
+ return false;
216
+ const entries = [];
217
+ for (const key of Reflect.ownKeys(current)) {
218
+ if (typeof key !== "string" || key.length > CONTRACT_MAX_IDENTIFIER_LENGTH)
219
+ return false;
220
+ const descriptor = Object.getOwnPropertyDescriptor(current, key);
221
+ if (descriptor === undefined || !descriptor.enumerable || !("value" in descriptor))
222
+ return false;
223
+ if (descriptor.value === undefined && omitUndefinedObjectFields)
224
+ continue;
225
+ entries.push([key, descriptor]);
226
+ if (entries.length > CONTRACT_MAX_MAP_ENTRIES)
227
+ return false;
228
+ }
229
+ if (!addBytes(2 + Math.max(entries.length - 1, 0)))
230
+ return false;
231
+ for (const [key, descriptor] of entries) {
232
+ if (!addBytes(serializedJsonStringBytes(key) + 1))
233
+ return false;
234
+ pending.push({
235
+ value: descriptor.value,
236
+ depth: item.depth + 1,
237
+ omitUndefined: omitUndefinedObjectFields,
238
+ });
239
+ }
240
+ }
241
+ return true;
242
+ }
87
243
  /** Validate digest input while matching JSON's omission of undefined object fields. */
88
244
  export function isBoundedJsonMaterial(value) {
89
245
  const pending = [{ value, depth: 0 }];
@@ -158,6 +314,13 @@ export const boundedJsonRecordSchema = z.custom((value) => typeof value === "obj
158
314
  value !== null &&
159
315
  !Array.isArray(value) &&
160
316
  isBoundedJsonValue(value), { message: "metadata exceeds the contract bounds or is not a JSON object" });
317
+ /** One provider event payload or terminal response, bounded as serialized UTF-8 JSON. */
318
+ export const boundedEventContentJsonSchema = z.custom(isBoundedEventContentJson, { message: "event content exceeds its serialized byte bound or is not finite JSON" });
319
+ export const boundedEventContentRecordSchema = z.custom((value) => typeof value === "object" &&
320
+ value !== null &&
321
+ !Array.isArray(value) &&
322
+ isBoundedEventContentJson(value), { message: "event content exceeds its serialized byte bound or is not a JSON object" });
323
+ export const boundedEventContentStringSchema = z.custom((value) => typeof value === "string" && isBoundedEventContentJson(value), { message: "event content exceeds its serialized byte bound or is not a string" });
161
324
  export function assertBoundedJson(value) {
162
325
  if (!isBoundedJsonValue(value)) {
163
326
  throw new Error("value exceeds the contract bounds or is not finite JSON");
@@ -257,7 +257,7 @@ export interface AgentTurnResult {
257
257
  }
258
258
  /** Runtime validator for a provider turn returned from durable continuation. */
259
259
  export declare const AgentTurnResultSchema: z.ZodObject<{
260
- text: z.ZodString;
260
+ text: z.ZodCustom<string, string>;
261
261
  success: z.ZodBoolean;
262
262
  error: z.ZodOptional<z.ZodString>;
263
263
  sessionId: z.ZodOptional<z.ZodString>;
@@ -413,7 +413,7 @@ export declare const AgentNativeContextContinuationResultSchema: z.ZodUnion<read
413
413
  }>;
414
414
  }, z.core.$strip>>;
415
415
  result: z.ZodObject<{
416
- text: z.ZodString;
416
+ text: z.ZodCustom<string, string>;
417
417
  success: z.ZodBoolean;
418
418
  error: z.ZodOptional<z.ZodString>;
419
419
  sessionId: z.ZodOptional<z.ZodString>;
@@ -5,7 +5,7 @@ import { InteractionCapabilitiesSchema, RequestedInteractionsSchema } from "./in
5
5
  import { ContextTransferReceiptSchema, ContextTransferRequestSchema, NativeContextBoundaryProofSchema, NativeContextContinuationAcknowledgementSchema, NativeContextContinuationRequestSchema, nativeContextContinuationAcknowledgementMatches } from "./portable-context.js";
6
6
  import { AgentExactRunControlRefSchema, AgentRunControlRefSchema, CanonicalStreamEventSchema } from "./runtime-control.js";
7
7
  import { AgentProfileCapabilitiesSchema } from "./environment-profile-capabilities.js";
8
- import { boundedIdentifierSchema, boundedJsonRecordSchema, boundedJsonSchema, boundedStringSchema, CONTRACT_MAX_ARRAY_LENGTH } from "./contract-limits.js";
8
+ import { boundedEventContentJsonSchema, boundedEventContentRecordSchema, boundedEventContentStringSchema, boundedIdentifierSchema, boundedJsonRecordSchema, boundedStringSchema, CONTRACT_MAX_ARRAY_LENGTH } from "./contract-limits.js";
9
9
  import { InputPartSchema } from "./portable-context-shared.js";
10
10
  import { deepFreeze } from "./deep-freeze.js";
11
11
  export const AgentTurnInputSchema = z.strictObject({
@@ -37,16 +37,16 @@ const TokenUsageSchema = z.strictObject({
37
37
  });
38
38
  const AgentEnvironmentEventSchema = z.strictObject({
39
39
  type: boundedIdentifierSchema,
40
- data: boundedJsonRecordSchema,
40
+ data: boundedEventContentRecordSchema,
41
41
  id: boundedIdentifierSchema.optional(),
42
42
  normalized: CanonicalStreamEventSchema.optional(),
43
43
  usage: TokenUsageSchema.optional(),
44
44
  usageMode: z.enum(["delta", "cumulative"]).optional(),
45
- providerEvent: boundedJsonSchema.optional(),
45
+ providerEvent: boundedEventContentJsonSchema.optional(),
46
46
  });
47
47
  /** Runtime validator for a provider turn returned from durable continuation. */
48
48
  export const AgentTurnResultSchema = z.strictObject({
49
- text: boundedStringSchema,
49
+ text: boundedEventContentStringSchema,
50
50
  success: z.boolean(),
51
51
  error: boundedStringSchema.optional(),
52
52
  sessionId: boundedIdentifierSchema.optional(),
package/dist/index.d.ts CHANGED
@@ -40,5 +40,5 @@ export * from "./harness-capabilities.js";
40
40
  export * from "./profile-schema.js";
41
41
  export * from "./profile-security.js";
42
42
  export * from "./sandbox-size.js";
43
- export { CONTRACT_MAX_CONFIDENTIAL_ATTESTATION_QUOTE_LENGTH, } from "./contract-limits.js";
43
+ export { CONTRACT_MAX_CONFIDENTIAL_ATTESTATION_QUOTE_LENGTH, CONTRACT_MAX_JSON_BYTES, boundedEventContentJsonSchema, boundedEventContentRecordSchema, boundedEventContentStringSchema, isBoundedEventContentJson, } from "./contract-limits.js";
44
44
  export { AgentEnvironmentEgressPolicySchema } from "./environment-requests.js";
package/dist/index.js CHANGED
@@ -38,5 +38,5 @@ export * from "./harness-capabilities.js";
38
38
  export * from "./profile-schema.js";
39
39
  export * from "./profile-security.js";
40
40
  export * from "./sandbox-size.js";
41
- export { CONTRACT_MAX_CONFIDENTIAL_ATTESTATION_QUOTE_LENGTH, } from "./contract-limits.js";
41
+ export { CONTRACT_MAX_CONFIDENTIAL_ATTESTATION_QUOTE_LENGTH, CONTRACT_MAX_JSON_BYTES, boundedEventContentJsonSchema, boundedEventContentRecordSchema, boundedEventContentStringSchema, isBoundedEventContentJson, } from "./contract-limits.js";
42
42
  export { AgentEnvironmentEgressPolicySchema } from "./environment-requests.js";
@@ -49,6 +49,11 @@ export interface AgentProfileDiff {
49
49
  description?: string;
50
50
  rationale?: string;
51
51
  source?: {
52
+ /**
53
+ * Who produced this change. `frontier-author` is an agent that wrote it —
54
+ * the same member {@link AgentCandidateLineage}`.source` carries, so the two
55
+ * enums name one actor with one word.
56
+ */
52
57
  kind: "trace" | "frontier-author" | "human" | "optimizer" | "compound";
53
58
  artifacts?: readonly string[];
54
59
  notes?: readonly string[];
@@ -164,7 +164,6 @@ export declare const AgentRunControlAcknowledgementSchema: z.ZodObject<{
164
164
  existingRequestDigest: z.ZodOptional<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>;
165
165
  }, z.core.$strict>;
166
166
  export declare function agentRunControlAcknowledgementMatchesRequest(request: AgentRunControlRequest, acknowledgement: AgentRunControlAcknowledgement): boolean;
167
- /** Runtime validator for every member of the existing canonical event union. */
168
167
  export declare const CanonicalStreamEventSchema: z.ZodType<StreamEvent>;
169
168
  /** Ordered, replayable envelope around the existing canonical event union. */
170
169
  export interface RuntimeEventEnvelope {
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { canonicalCandidateDigest, sha256DigestSchema, } from "./agent-candidate-schema-common.js";
3
- import { boundedIdentifierSchema, boundedJsonRecordSchema, boundedJsonSchema, boundedStringSchema, } from "./contract-limits.js";
3
+ import { boundedEventContentJsonSchema, boundedEventContentRecordSchema, boundedEventContentStringSchema, boundedIdentifierSchema, boundedJsonRecordSchema, boundedStringSchema, isBoundedEventContentJson, } from "./contract-limits.js";
4
4
  import { ModelUsageSchema } from "./environment-observation.js";
5
5
  import { InteractionRequestSchema } from "./interaction.js";
6
6
  import { DurablePlanSchema } from "./plan.js";
@@ -213,20 +213,20 @@ const toolTimeSchema = z.strictObject({
213
213
  const toolStateSchema = z.discriminatedUnion("status", [
214
214
  z.strictObject({
215
215
  status: z.literal("pending"),
216
- input: unknownRecordSchema,
217
- raw: boundedStringSchema.optional(),
216
+ input: boundedEventContentRecordSchema,
217
+ raw: boundedEventContentStringSchema.optional(),
218
218
  }),
219
219
  z.strictObject({
220
220
  status: z.literal("running"),
221
- input: unknownRecordSchema,
221
+ input: boundedEventContentRecordSchema,
222
222
  title: boundedStringSchema.optional(),
223
223
  metadata: unknownRecordSchema.optional(),
224
224
  time: z.strictObject({ start: z.number().finite() }).optional(),
225
225
  }),
226
226
  z.strictObject({
227
227
  status: z.literal("completed"),
228
- input: unknownRecordSchema,
229
- output: boundedJsonSchema,
228
+ input: boundedEventContentRecordSchema,
229
+ output: boundedEventContentJsonSchema,
230
230
  title: boundedStringSchema.optional(),
231
231
  metadata: unknownRecordSchema.optional(),
232
232
  time: z.strictObject({
@@ -236,15 +236,15 @@ const toolStateSchema = z.discriminatedUnion("status", [
236
236
  }),
237
237
  z.strictObject({
238
238
  status: z.enum(["error", "failed"]),
239
- input: unknownRecordSchema,
239
+ input: boundedEventContentRecordSchema,
240
240
  error: boundedStringSchema.optional(),
241
- output: boundedJsonSchema.optional(),
241
+ output: boundedEventContentJsonSchema.optional(),
242
242
  metadata: unknownRecordSchema.optional(),
243
243
  time: toolTimeSchema.optional(),
244
244
  }),
245
245
  ]);
246
246
  const partSchema = z.discriminatedUnion("type", [
247
- z.strictObject({ ...partBase, type: z.literal("text"), text: boundedStringSchema }),
247
+ z.strictObject({ ...partBase, type: z.literal("text"), text: boundedEventContentStringSchema }),
248
248
  z.strictObject({
249
249
  ...partBase,
250
250
  type: z.literal("tool"),
@@ -256,7 +256,7 @@ const partSchema = z.discriminatedUnion("type", [
256
256
  z.strictObject({
257
257
  ...partBase,
258
258
  type: z.literal("reasoning"),
259
- text: boundedStringSchema,
259
+ text: boundedEventContentStringSchema,
260
260
  }),
261
261
  z.strictObject({
262
262
  ...partBase,
@@ -338,11 +338,11 @@ const ChildTaskEventSchema = z
338
338
  }
339
339
  });
340
340
  /** Runtime validator for every member of the existing canonical event union. */
341
- export const CanonicalStreamEventSchema = z.discriminatedUnion("type", [
341
+ const CanonicalStreamEventUnionSchema = z.discriminatedUnion("type", [
342
342
  z.strictObject({
343
343
  type: z.literal("message.part.updated"),
344
344
  part: partSchema,
345
- delta: boundedStringSchema.optional(),
345
+ delta: boundedEventContentStringSchema.optional(),
346
346
  }),
347
347
  z.strictObject({
348
348
  type: z.literal("tool-heartbeat"),
@@ -382,7 +382,7 @@ export const CanonicalStreamEventSchema = z.discriminatedUnion("type", [
382
382
  z.strictObject({
383
383
  type: z.literal("raw"),
384
384
  backend: stableIdSchema,
385
- event: boundedJsonSchema,
385
+ event: boundedEventContentJsonSchema,
386
386
  }),
387
387
  z.strictObject({
388
388
  type: z.literal("session.updated"),
@@ -408,6 +408,17 @@ export const CanonicalStreamEventSchema = z.discriminatedUnion("type", [
408
408
  }),
409
409
  ChildTaskEventSchema,
410
410
  ]);
411
+ export const CanonicalStreamEventSchema = CanonicalStreamEventUnionSchema.superRefine((event, refinement) => {
412
+ // Zod retains explicitly supplied optional `undefined` fields, whereas a
413
+ // JSON event omits them. Canonical events use that wire-equivalent omission
414
+ // without making raw provider records accept undefined.
415
+ if (!isBoundedEventContentJson(event, { omitUndefinedObjectFields: true })) {
416
+ refinement.addIssue({
417
+ code: "custom",
418
+ message: "canonical stream event exceeds its serialized byte bound",
419
+ });
420
+ }
421
+ });
411
422
  export const RuntimeEventEnvelopeSchema = z.strictObject({
412
423
  runId: stableIdSchema,
413
424
  eventId: stableIdSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-interface",
3
- "version": "2.5.0",
3
+ "version": "2.6.1",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",