@tangle-network/agent-interface 0.28.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/agent-candidate-code-schema.d.ts +0 -8
  2. package/dist/agent-candidate-code-schema.js +0 -1
  3. package/dist/agent-candidate-execution-plan-schema.d.ts +193 -350
  4. package/dist/agent-candidate-execution-plan-schema.js +98 -131
  5. package/dist/agent-candidate-lineage-schema.d.ts +1 -28
  6. package/dist/agent-candidate-lineage-schema.js +3 -33
  7. package/dist/agent-candidate-outcome-schema.d.ts +48 -18
  8. package/dist/agent-candidate-outcome-schema.js +19 -24
  9. package/dist/agent-candidate-profile-schema.d.ts +3 -28
  10. package/dist/agent-candidate-profile-schema.js +15 -27
  11. package/dist/agent-candidate-promotion-schema.d.ts +10981 -2356
  12. package/dist/agent-candidate-promotion-schema.js +495 -105
  13. package/dist/agent-candidate-receipt-schema.d.ts +268 -303
  14. package/dist/agent-candidate-receipt-schema.js +82 -8
  15. package/dist/agent-candidate-schema-common.d.ts +8 -0
  16. package/dist/agent-candidate-schema-common.js +35 -1
  17. package/dist/agent-candidate-schema.d.ts +3 -52
  18. package/dist/agent-candidate-schema.js +3 -28
  19. package/dist/agent-candidate-task-schema.d.ts +643 -0
  20. package/dist/agent-candidate-task-schema.js +191 -0
  21. package/dist/agent-candidate.d.ts +191 -75
  22. package/dist/agent-candidate.test-fixture.d.ts +0 -26
  23. package/dist/agent-candidate.test-fixture.js +0 -26
  24. package/dist/agent-profile.d.ts +33 -9
  25. package/dist/harness-capabilities.d.ts +2 -2
  26. package/dist/harness-capabilities.js +23 -14
  27. package/dist/profile-schema.d.ts +65 -84
  28. package/dist/profile-schema.js +82 -32
  29. package/dist/profile-security.js +2 -0
  30. package/package.json +2 -2
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { agentCandidateArtifactRefSchema, agentCandidateCapturedArtifactSchema, agentCandidateWorkspaceSnapshotEvidenceSchema, } from "./agent-candidate-artifact-schema.js";
3
- import { agentCandidateExecutionPlanEvidenceSchema, agentCandidateProfilePlanEvidenceSchema, agentCandidateResolvedModelSchema, } from "./agent-candidate-execution-plan-schema.js";
3
+ import { agentCandidateExecutionPlanEvidenceSchema, agentCandidateProfileActivationSchema, agentCandidateResolvedModelSchema, } from "./agent-candidate-execution-plan-schema.js";
4
4
  import { agentCandidateBenchmarkResultEvidenceSchema, agentCandidateModelSettlementEvidenceSchema, agentCandidateTaskOutcomeEvidenceSchema, } from "./agent-candidate-outcome-schema.js";
5
5
  import { gitObjectSchema, isCanonicalJsonValue, isSafeRelativePath, sha256DigestSchema, } from "./agent-candidate-schema-common.js";
6
6
  import { harnessTypeSchema } from "./harness.js";
@@ -20,6 +20,34 @@ const ociPlatformSchema = z
20
20
  variant: z.string().min(1).optional(),
21
21
  })
22
22
  .strict();
23
+ const benchmarkMaterialEvidenceSchema = z
24
+ .object({
25
+ digest: sha256DigestSchema,
26
+ material: agentCandidateCapturedArtifactSchema,
27
+ })
28
+ .strict()
29
+ .superRefine((evidence, ctx) => {
30
+ if (evidence.material.sha256 !== evidence.digest) {
31
+ ctx.addIssue({
32
+ code: "custom",
33
+ path: ["material", "sha256"],
34
+ message: "benchmark material artifact must match its canonical digest",
35
+ });
36
+ }
37
+ if (evidence.material.byteLength === 0) {
38
+ ctx.addIssue({
39
+ code: "custom",
40
+ path: ["material", "byteLength"],
41
+ message: "benchmark material artifact must contain canonical bytes",
42
+ });
43
+ }
44
+ });
45
+ export const agentCandidateBenchmarkInputEvidenceSchema = z
46
+ .object({
47
+ suite: benchmarkMaterialEvidenceSchema,
48
+ task: benchmarkMaterialEvidenceSchema,
49
+ })
50
+ .strict();
23
51
  export const agentCandidateTraceEvidenceSchema = z
24
52
  .object({
25
53
  artifact: agentCandidateCapturedArtifactSchema,
@@ -77,7 +105,8 @@ export const agentCandidateMaterializationReceiptSchema = z
77
105
  kind: z.literal("agent-candidate-materialization"),
78
106
  digestAlgorithm: z.literal("rfc8785-sha256"),
79
107
  bundleDigest: sha256DigestSchema,
80
- profilePlan: agentCandidateProfilePlanEvidenceSchema,
108
+ benchmark: agentCandidateBenchmarkInputEvidenceSchema,
109
+ profileActivation: agentCandidateProfileActivationSchema,
81
110
  executionPlan: agentCandidateExecutionPlanEvidenceSchema,
82
111
  candidateWorkspace: agentCandidateWorkspaceSnapshotEvidenceSchema.optional(),
83
112
  codeKind: z.enum(["disabled", "no-op", "git-patch"]),
@@ -133,18 +162,28 @@ export const agentCandidateMaterializationReceiptSchema = z
133
162
  }
134
163
  const checks = [
135
164
  [
136
- receipt.bundleDigest === plan.bundleDigest,
137
- ["executionPlan", "material", "bundleDigest"],
165
+ receipt.bundleDigest === plan.runCell.bundleDigest,
166
+ ["executionPlan", "material", "runCell", "bundleDigest"],
138
167
  "execution plan must bind the receipt bundle",
139
168
  ],
140
169
  [
141
- receipt.profilePlan.digest === plan.profile.planDigest,
170
+ receipt.benchmark.suite.digest === plan.runCell.suiteDigest,
171
+ ["benchmark", "suite", "digest"],
172
+ "execution plan must bind the captured benchmark suite",
173
+ ],
174
+ [
175
+ receipt.benchmark.task.digest === plan.runCell.taskDigest,
176
+ ["benchmark", "task", "digest"],
177
+ "execution plan must bind the captured benchmark task",
178
+ ],
179
+ [
180
+ receipt.profileActivation.profilePlan.digest === plan.profile.planDigest,
142
181
  ["executionPlan", "material", "profile", "planDigest"],
143
182
  "execution plan must bind the exact profile plan",
144
183
  ],
145
184
  [
146
185
  JSON.stringify(plan.profile.mountPaths) ===
147
- JSON.stringify(receipt.profilePlan.material.files.map((file) => file.relPath)),
186
+ JSON.stringify(receipt.profileActivation.profilePlan.material.files.map((file) => file.relPath)),
148
187
  ["executionPlan", "material", "profile", "mountPaths"],
149
188
  "execution plan must bind every profile mount path",
150
189
  ],
@@ -189,8 +228,8 @@ export const agentCandidateMaterializationReceiptSchema = z
189
228
  "execution plan must bind the exact uploaded candidate workspace",
190
229
  ],
191
230
  [
192
- receipt.profilePlan.material.harness === receipt.harness,
193
- ["profilePlan", "material", "harness"],
231
+ receipt.profileActivation.profilePlan.material.harness === receipt.harness,
232
+ ["profileActivation", "profilePlan", "material", "harness"],
194
233
  "profile plan harness must match materialization",
195
234
  ],
196
235
  ];
@@ -210,8 +249,16 @@ export const agentCandidateRunReceiptSchema = z
210
249
  kind: z.literal("agent-candidate-run"),
211
250
  digestAlgorithm: z.literal("rfc8785-sha256"),
212
251
  bundleDigest: sha256DigestSchema,
252
+ runCellDigest: sha256DigestSchema,
213
253
  materializationReceiptDigest: sha256DigestSchema,
214
254
  executionPlanDigest: sha256DigestSchema,
255
+ timing: z
256
+ .object({
257
+ startedAtMs: z.number().int().nonnegative().safe(),
258
+ endedAtMs: z.number().int().nonnegative().safe(),
259
+ durationMs: z.number().int().nonnegative().safe(),
260
+ })
261
+ .strict(),
215
262
  memory: agentCandidateMemoryReceiptSchema,
216
263
  trace: agentCandidateTraceEvidenceSchema,
217
264
  termination: agentCandidateTerminationSchema,
@@ -223,6 +270,15 @@ export const agentCandidateRunReceiptSchema = z
223
270
  })
224
271
  .strict()
225
272
  .superRefine((receipt, ctx) => {
273
+ if (receipt.timing.endedAtMs < receipt.timing.startedAtMs ||
274
+ receipt.timing.durationMs !==
275
+ receipt.timing.endedAtMs - receipt.timing.startedAtMs) {
276
+ ctx.addIssue({
277
+ code: "custom",
278
+ path: ["timing"],
279
+ message: "run timing must be ordered and internally consistent",
280
+ });
281
+ }
226
282
  if (receipt.modelSettlement.material.executionPlanDigest !==
227
283
  receipt.executionPlanDigest) {
228
284
  ctx.addIssue({
@@ -231,6 +287,24 @@ export const agentCandidateRunReceiptSchema = z
231
287
  message: "model settlement must bind the executed plan",
232
288
  });
233
289
  }
290
+ for (const [index, call] of receipt.modelSettlement.material.calls.entries()) {
291
+ if (call.startedAtMs < receipt.timing.startedAtMs ||
292
+ call.endedAtMs > receipt.timing.endedAtMs) {
293
+ ctx.addIssue({
294
+ code: "custom",
295
+ path: ["modelSettlement", "material", "calls", index],
296
+ message: "model calls must occur within the recorded run",
297
+ });
298
+ }
299
+ }
300
+ if (receipt.benchmarkResult.material.grading.timing.startedAtMs <
301
+ receipt.timing.endedAtMs) {
302
+ ctx.addIssue({
303
+ code: "custom",
304
+ path: ["benchmarkResult", "material", "grading", "timing", "startedAtMs"],
305
+ message: "grading must start after candidate execution ends",
306
+ });
307
+ }
234
308
  if (receipt.trace.modelCallCount !==
235
309
  receipt.modelSettlement.material.usage.modelCalls) {
236
310
  ctx.addIssue({
@@ -6,6 +6,14 @@ export declare const environmentNameSchema: z.ZodString;
6
6
  export declare const headerNameSchema: z.ZodString;
7
7
  export declare const agentCandidateMediaTypeSchema: z.ZodString;
8
8
  export declare function sha256Utf8(value: string): Sha256Digest;
9
+ export declare function sha256Bytes(value: Uint8Array): Sha256Digest;
10
+ /** RFC 8785 serialization used by every candidate-producing package. */
11
+ export declare function canonicalCandidateJson(value: unknown): string;
12
+ export declare function canonicalCandidateBytes(value: unknown): Uint8Array;
13
+ export declare function canonicalCandidateDigest(value: unknown): Sha256Digest;
14
+ export declare function omitTopLevelDigest<T extends {
15
+ digest: Sha256Digest;
16
+ }>(value: T): Omit<T, "digest">;
9
17
  export declare function isWellFormedUnicode(value: string): boolean;
10
18
  export declare function isSafeRelativePath(value: string, allowDot: boolean): boolean;
11
19
  export declare function isSafeExecutable(value: string): boolean;
@@ -33,10 +33,44 @@ export const environmentNameSchema = z.string().regex(environmentNamePattern);
33
33
  export const headerNameSchema = z.string().regex(headerNamePattern);
34
34
  export const agentCandidateMediaTypeSchema = z.string().regex(mediaTypePattern);
35
35
  export function sha256Utf8(value) {
36
- const bytes = sha256(new TextEncoder().encode(value));
36
+ return sha256Bytes(new TextEncoder().encode(value));
37
+ }
38
+ export function sha256Bytes(value) {
39
+ const bytes = sha256(value);
37
40
  const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
38
41
  return `sha256:${hex}`;
39
42
  }
43
+ /** RFC 8785 serialization used by every candidate-producing package. */
44
+ export function canonicalCandidateJson(value) {
45
+ if (!isCanonicalJsonValue(value)) {
46
+ throw new Error("candidate document must be finite, acyclic RFC 8785 JSON");
47
+ }
48
+ return serializeCanonicalCandidate(value);
49
+ }
50
+ export function canonicalCandidateBytes(value) {
51
+ return new TextEncoder().encode(canonicalCandidateJson(value));
52
+ }
53
+ export function canonicalCandidateDigest(value) {
54
+ return sha256Bytes(canonicalCandidateBytes(value));
55
+ }
56
+ export function omitTopLevelDigest(value) {
57
+ const { digest: _digest, ...material } = value;
58
+ return material;
59
+ }
60
+ function serializeCanonicalCandidate(value) {
61
+ if (value === null || typeof value === "boolean" || typeof value === "number") {
62
+ return JSON.stringify(value);
63
+ }
64
+ if (typeof value === "string")
65
+ return JSON.stringify(value);
66
+ if (Array.isArray(value)) {
67
+ return `[${value.map(serializeCanonicalCandidate).join(",")}]`;
68
+ }
69
+ return `{${Object.keys(value)
70
+ .sort()
71
+ .map((key) => `${JSON.stringify(key)}:${serializeCanonicalCandidate(value[key])}`)
72
+ .join(",")}}`;
73
+ }
40
74
  export function isWellFormedUnicode(value) {
41
75
  for (let index = 0; index < value.length; index++) {
42
76
  const code = value.charCodeAt(index);
@@ -61,20 +61,7 @@ export declare const agentCandidateBundleSchema: z.ZodObject<{
61
61
  deny: "deny";
62
62
  }>>]>>>;
63
63
  tools: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
64
- mcp: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
65
- transport: z.ZodOptional<z.ZodLiteral<"stdio">>;
66
- command: z.ZodOptional<z.ZodString>;
67
- args: z.ZodOptional<z.ZodArray<z.ZodObject<{
68
- kind: z.ZodLiteral<"public">;
69
- value: z.ZodString;
70
- }, z.core.$strict>>>;
71
- env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
72
- kind: z.ZodLiteral<"public">;
73
- value: z.ZodString;
74
- }, z.core.$strict>>>;
75
- cwd: z.ZodOptional<z.ZodString>;
76
- enabled: z.ZodOptional<z.ZodBoolean>;
77
- }, z.core.$strict>>>;
64
+ mcp: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<import("./agent-candidate.js").AgentCandidateMcpServer, unknown, z.core.$ZodTypeInternals<import("./agent-candidate.js").AgentCandidateMcpServer, unknown>>>>;
78
65
  subagents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
79
66
  prompt: z.ZodOptional<z.ZodString>;
80
67
  permissions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodEnum<{
@@ -250,10 +237,6 @@ export declare const agentCandidateBundleSchema: z.ZodObject<{
250
237
  }, z.core.$strict>;
251
238
  code: z.ZodDiscriminatedUnion<[z.ZodObject<{
252
239
  kind: z.ZodLiteral<"disabled">;
253
- reason: z.ZodEnum<{
254
- control: "control";
255
- "not-applicable": "not-applicable";
256
- }>;
257
240
  }, z.core.$strict>, z.ZodObject<{
258
241
  kind: z.ZodLiteral<"no-op">;
259
242
  reason: z.ZodLiteral<"proposer-no-change">;
@@ -535,39 +518,6 @@ export declare const agentCandidateBundleSchema: z.ZodObject<{
535
518
  byteLength: z.ZodNumber;
536
519
  }, z.core.$strict>>;
537
520
  }, z.core.$strict>], "mode">;
538
- lineage: z.ZodObject<{
539
- source: z.ZodEnum<{
540
- optimizer: "optimizer";
541
- human: "human";
542
- import: "import";
543
- compound: "compound";
544
- }>;
545
- parentDigests: z.ZodOptional<z.ZodArray<z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>>>;
546
- runIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
547
- profileDiffIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
548
- modelSnapshots: z.ZodOptional<z.ZodArray<z.ZodString>>;
549
- benchmark: z.ZodOptional<z.ZodObject<{
550
- name: z.ZodString;
551
- version: z.ZodString;
552
- splitDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
553
- }, z.core.$strict>>;
554
- spend: z.ZodOptional<z.ZodObject<{
555
- proposal: z.ZodObject<{
556
- costUsd: z.ZodNumber;
557
- inputTokens: z.ZodNumber;
558
- outputTokens: z.ZodNumber;
559
- cachedInputTokens: z.ZodOptional<z.ZodNumber>;
560
- modelCalls: z.ZodNumber;
561
- }, z.core.$strict>;
562
- evaluation: z.ZodObject<{
563
- costUsd: z.ZodNumber;
564
- inputTokens: z.ZodNumber;
565
- outputTokens: z.ZodNumber;
566
- cachedInputTokens: z.ZodOptional<z.ZodNumber>;
567
- modelCalls: z.ZodNumber;
568
- }, z.core.$strict>;
569
- }, z.core.$strict>>;
570
- }, z.core.$strict>;
571
521
  digest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
572
522
  }, z.core.$strict>;
573
523
  export * from "./agent-candidate-artifact-schema.js";
@@ -577,4 +527,5 @@ export * from "./agent-candidate-lineage-schema.js";
577
527
  export * from "./agent-candidate-outcome-schema.js";
578
528
  export * from "./agent-candidate-profile-schema.js";
579
529
  export * from "./agent-candidate-receipt-schema.js";
580
- export { sha256DigestSchema } from "./agent-candidate-schema-common.js";
530
+ export * from "./agent-candidate-task-schema.js";
531
+ export { canonicalCandidateBytes, canonicalCandidateDigest, canonicalCandidateJson, omitTopLevelDigest, sha256Bytes, sha256DigestSchema, sha256Utf8, } from "./agent-candidate-schema-common.js";
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { agentCandidateCodeSchema, agentCandidateExecutionSchema } from "./agent-candidate-code-schema.js";
3
3
  import { agentCandidateProfileSchema } from "./agent-candidate-profile-schema.js";
4
- import { agentCandidateKnowledgeSchema, agentCandidateLineageSchema, agentCandidateMemoryPolicySchema, } from "./agent-candidate-lineage-schema.js";
4
+ import { agentCandidateKnowledgeSchema, agentCandidateMemoryPolicySchema, } from "./agent-candidate-lineage-schema.js";
5
5
  import { isCanonicalJsonValue, sha256DigestSchema, } from "./agent-candidate-schema-common.js";
6
6
  import { canonicalizeHarness } from "./harness.js";
7
7
  /**
@@ -21,7 +21,6 @@ export const agentCandidateBundleSchema = z
21
21
  execution: agentCandidateExecutionSchema,
22
22
  knowledge: agentCandidateKnowledgeSchema.optional(),
23
23
  memory: agentCandidateMemoryPolicySchema,
24
- lineage: agentCandidateLineageSchema,
25
24
  digest: sha256DigestSchema,
26
25
  })
27
26
  .strict()
@@ -41,13 +40,6 @@ export const agentCandidateBundleSchema = z
41
40
  message: "execution harness must match the candidate profile preference",
42
41
  });
43
42
  }
44
- if (bundle.lineage.parentDigests?.includes(bundle.digest)) {
45
- ctx.addIssue({
46
- code: "custom",
47
- path: ["lineage", "parentDigests"],
48
- message: "a candidate cannot name itself as a parent",
49
- });
50
- }
51
43
  if (bundle.code.kind === "disabled") {
52
44
  if (bundle.execution.cwd.workspace !== "task") {
53
45
  ctx.addIssue({
@@ -70,15 +62,6 @@ export const agentCandidateBundleSchema = z
70
62
  message: "disabled code cannot carry a candidate workspace",
71
63
  });
72
64
  }
73
- if (bundle.code.reason === "control" &&
74
- (bundle.lineage.source === "optimizer" ||
75
- bundle.lineage.source === "compound")) {
76
- ctx.addIssue({
77
- code: "custom",
78
- path: ["lineage", "source"],
79
- message: "fixed controls cannot claim proposer lineage",
80
- });
81
- }
82
65
  }
83
66
  else {
84
67
  const launch = bundle.execution.launch;
@@ -121,15 +104,6 @@ export const agentCandidateBundleSchema = z
121
104
  });
122
105
  }
123
106
  }
124
- if (bundle.code.kind === "no-op" &&
125
- bundle.lineage.source !== "optimizer" &&
126
- bundle.lineage.source !== "compound") {
127
- ctx.addIssue({
128
- code: "custom",
129
- path: ["lineage", "source"],
130
- message: "proposer no-op candidates require optimizer or compound lineage",
131
- });
132
- }
133
107
  }
134
108
  });
135
109
  const _bundleSchemaMatchesType = true;
@@ -141,4 +115,5 @@ export * from "./agent-candidate-lineage-schema.js";
141
115
  export * from "./agent-candidate-outcome-schema.js";
142
116
  export * from "./agent-candidate-profile-schema.js";
143
117
  export * from "./agent-candidate-receipt-schema.js";
144
- export { sha256DigestSchema } from "./agent-candidate-schema-common.js";
118
+ export * from "./agent-candidate-task-schema.js";
119
+ export { canonicalCandidateBytes, canonicalCandidateDigest, canonicalCandidateJson, omitTopLevelDigest, sha256Bytes, sha256DigestSchema, sha256Utf8, } from "./agent-candidate-schema-common.js";