@tangle-network/agent-interface 0.36.0 → 0.38.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 (31) hide show
  1. package/README.md +2 -2
  2. package/dist/agent-candidate-artifact-schema.d.ts +504 -0
  3. package/dist/agent-candidate-artifact-schema.js +16 -1
  4. package/dist/agent-candidate-execution-plan-schema.d.ts +50 -27
  5. package/dist/agent-candidate-execution-plan-schema.js +4 -16
  6. package/dist/agent-candidate-profile-schema.d.ts +341 -25
  7. package/dist/agent-candidate-promotion-schema.d.ts +2320 -287
  8. package/dist/agent-candidate-receipt-schema.d.ts +50 -27
  9. package/dist/agent-candidate-schema-common.js +1 -1
  10. package/dist/agent-candidate-schema.d.ts +341 -25
  11. package/dist/agent-candidate.d.ts +7 -8
  12. package/dist/agent-execution-preparation.d.ts +366 -0
  13. package/dist/agent-execution-preparation.js +793 -0
  14. package/dist/agent-improvement-source.d.ts +61 -3
  15. package/dist/agent-improvement-source.js +122 -8
  16. package/dist/agent-profile-activation.d.ts +41 -0
  17. package/dist/agent-profile-activation.js +24 -0
  18. package/dist/agent-profile-improvement-schema.d.ts +48 -4
  19. package/dist/agent-profile-materialization.d.ts +34 -0
  20. package/dist/agent-profile-materialization.js +243 -0
  21. package/dist/agent-profile.d.ts +44 -7
  22. package/dist/agent-profile.js +39 -2
  23. package/dist/agent-workspace-lease.d.ts +138 -0
  24. package/dist/agent-workspace-lease.js +203 -0
  25. package/dist/harness-capabilities.d.ts +1 -1
  26. package/dist/harness-capabilities.js +2 -9
  27. package/dist/index.d.ts +4 -0
  28. package/dist/index.js +4 -0
  29. package/dist/profile-schema.d.ts +142 -84
  30. package/dist/profile-schema.js +152 -41
  31. package/package.json +3 -1
@@ -2,19 +2,77 @@ import { z } from "zod";
2
2
  import type { AgentCandidateJsonValue } from "./agent-candidate.js";
3
3
  /** Metadata key that binds a measured improvement to its exact external source. */
4
4
  export declare const AGENT_IMPROVEMENT_SOURCE_METADATA_KEY = "agentImprovementSource";
5
+ /** License terms retained with an imported source. */
6
+ export declare const agentSourceLicenseSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
7
+ kind: z.ZodLiteral<"spdx">;
8
+ expression: z.ZodString;
9
+ }, z.core.$strict>, z.ZodObject<{
10
+ kind: z.ZodLiteral<"custom">;
11
+ name: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
12
+ reference: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
13
+ termsDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
14
+ }, z.core.$strict>], "kind">;
15
+ export type AgentSourceLicense = z.infer<typeof agentSourceLicenseSchema>;
16
+ /**
17
+ * One content transition applied while importing a source.
18
+ *
19
+ * `identity` and `revision` pin the transformer. Input/output digests make the
20
+ * ordered chain auditable without embedding executable transformation code.
21
+ * `procedureDigest` pins the implementation and non-secret configuration used
22
+ * for that step.
23
+ */
24
+ export declare const agentSourceTransformationSchema: z.ZodObject<{
25
+ kind: z.ZodEnum<{
26
+ normalization: "normalization";
27
+ transformation: "transformation";
28
+ }>;
29
+ identity: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
30
+ revision: z.ZodUnion<readonly [z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>, z.ZodNumber]>;
31
+ procedureDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
32
+ inputDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
33
+ outputDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
34
+ }, z.core.$strict>;
35
+ export type AgentSourceTransformation = z.infer<typeof agentSourceTransformationSchema>;
5
36
  /**
6
37
  * Stable reference for the state from which an improvement candidate was made.
7
38
  * `sourceIdentity` identifies the provider object; `sourceDigest` is the exact
8
- * measured source state; `sourceRevision` is an
39
+ * measured source state consumed by the candidate; `sourceRevision` is an
9
40
  * opaque provider version retained to make stale-source errors intelligible to
10
41
  * callers. A revision may be numeric or textual because providers use both
11
42
  * counters and immutable revision identifiers.
43
+ *
44
+ * Optional license, attribution, and notice fields preserve obligations when a
45
+ * public source becomes an improvement input. When transformations are
46
+ * present, their first input pins the fetched source bytes, every adjacent
47
+ * digest must join, and the final output must equal `sourceDigest`.
12
48
  */
13
49
  export declare const agentImprovementSourceSchema: z.ZodObject<{
14
50
  kind: z.ZodString;
15
- sourceIdentity: z.ZodString;
51
+ sourceIdentity: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
16
52
  sourceDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
17
- sourceRevision: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
53
+ sourceRevision: z.ZodUnion<readonly [z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>, z.ZodNumber]>;
54
+ license: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
55
+ kind: z.ZodLiteral<"spdx">;
56
+ expression: z.ZodString;
57
+ }, z.core.$strict>, z.ZodObject<{
58
+ kind: z.ZodLiteral<"custom">;
59
+ name: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
60
+ reference: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
61
+ termsDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
62
+ }, z.core.$strict>], "kind">>;
63
+ attribution: z.ZodOptional<z.ZodArray<z.ZodString>>;
64
+ notices: z.ZodOptional<z.ZodArray<z.ZodString>>;
65
+ transformations: z.ZodOptional<z.ZodArray<z.ZodObject<{
66
+ kind: z.ZodEnum<{
67
+ normalization: "normalization";
68
+ transformation: "transformation";
69
+ }>;
70
+ identity: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
71
+ revision: z.ZodUnion<readonly [z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>, z.ZodNumber]>;
72
+ procedureDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
73
+ inputDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
74
+ outputDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
75
+ }, z.core.$strict>>>;
18
76
  }, z.core.$strict>;
19
77
  export type AgentImprovementSource = z.infer<typeof agentImprovementSourceSchema>;
20
78
  /** Attach one validated source reference to signed improvement metadata. */
@@ -1,26 +1,140 @@
1
+ import parseSpdxExpression from "spdx-expression-parse";
1
2
  import { z } from "zod";
2
- import { sha256DigestSchema } from "./agent-candidate-schema-common.js";
3
+ import { isWellFormedUnicode, looksLikeCredential, sha256DigestSchema, } from "./agent-candidate-schema-common.js";
3
4
  /** Metadata key that binds a measured improvement to its exact external source. */
4
5
  export const AGENT_IMPROVEMENT_SOURCE_METADATA_KEY = "agentImprovementSource";
6
+ function publicSourceTextSchema(maxLength, label) {
7
+ return z
8
+ .string()
9
+ .max(maxLength)
10
+ .refine(isWellFormedUnicode, `${label} must be well-formed Unicode`)
11
+ .refine((value) => !looksLikeCredential(value), `${label} cannot carry credentials`);
12
+ }
13
+ const sourceIdentitySchema = publicSourceTextSchema(256, "source identity")
14
+ .transform((value) => value.trim())
15
+ .pipe(z.string().min(1, "source identity cannot be blank"));
16
+ const sourceRevisionSchema = z.union([
17
+ publicSourceTextSchema(256, "source revision")
18
+ .transform((value) => value.trim())
19
+ .pipe(z.string().min(1, "source revision cannot be blank")),
20
+ z.number().int().nonnegative(),
21
+ ]);
22
+ const sourceStatementSchema = publicSourceTextSchema(16_384, "source statement").refine((value) => value.trim().length > 0, "statement cannot be blank");
23
+ const sourceStatementListSchema = z
24
+ .array(sourceStatementSchema)
25
+ .min(1)
26
+ .max(128)
27
+ .refine((values) => new Set(values).size === values.length, "statements must be unique");
28
+ function containsCustomLicenseReference(expression) {
29
+ if ("license" in expression) {
30
+ return (expression.license.startsWith("LicenseRef-") ||
31
+ expression.license.includes(":LicenseRef-"));
32
+ }
33
+ return (containsCustomLicenseReference(expression.left) ||
34
+ containsCustomLicenseReference(expression.right));
35
+ }
36
+ /** License terms retained with an imported source. */
37
+ export const agentSourceLicenseSchema = z.discriminatedUnion("kind", [
38
+ z
39
+ .object({
40
+ kind: z.literal("spdx"),
41
+ expression: z
42
+ .string()
43
+ .trim()
44
+ .min(1)
45
+ .max(1_024)
46
+ .refine((expression) => {
47
+ try {
48
+ return !containsCustomLicenseReference(parseSpdxExpression(expression));
49
+ }
50
+ catch {
51
+ return false;
52
+ }
53
+ }, "license expression must use standard SPDX identifiers; content-pin custom terms with kind=custom"),
54
+ })
55
+ .strict(),
56
+ z
57
+ .object({
58
+ kind: z.literal("custom"),
59
+ name: sourceIdentitySchema,
60
+ /** URL or repository-relative path from which the exact terms can be recovered. */
61
+ reference: publicSourceTextSchema(2_048, "license reference")
62
+ .transform((value) => value.trim())
63
+ .pipe(z.string().min(1, "license reference cannot be blank")),
64
+ /** Digest of the custom license text, not of its URL or file name. */
65
+ termsDigest: sha256DigestSchema,
66
+ })
67
+ .strict(),
68
+ ]);
69
+ /**
70
+ * One content transition applied while importing a source.
71
+ *
72
+ * `identity` and `revision` pin the transformer. Input/output digests make the
73
+ * ordered chain auditable without embedding executable transformation code.
74
+ * `procedureDigest` pins the implementation and non-secret configuration used
75
+ * for that step.
76
+ */
77
+ export const agentSourceTransformationSchema = z
78
+ .object({
79
+ kind: z.enum(["normalization", "transformation"]),
80
+ identity: sourceIdentitySchema,
81
+ revision: sourceRevisionSchema,
82
+ procedureDigest: sha256DigestSchema,
83
+ inputDigest: sha256DigestSchema,
84
+ outputDigest: sha256DigestSchema,
85
+ })
86
+ .strict();
5
87
  /**
6
88
  * Stable reference for the state from which an improvement candidate was made.
7
89
  * `sourceIdentity` identifies the provider object; `sourceDigest` is the exact
8
- * measured source state; `sourceRevision` is an
90
+ * measured source state consumed by the candidate; `sourceRevision` is an
9
91
  * opaque provider version retained to make stale-source errors intelligible to
10
92
  * callers. A revision may be numeric or textual because providers use both
11
93
  * counters and immutable revision identifiers.
94
+ *
95
+ * Optional license, attribution, and notice fields preserve obligations when a
96
+ * public source becomes an improvement input. When transformations are
97
+ * present, their first input pins the fetched source bytes, every adjacent
98
+ * digest must join, and the final output must equal `sourceDigest`.
12
99
  */
13
100
  export const agentImprovementSourceSchema = z
14
101
  .object({
15
102
  kind: z.string().trim().min(1).max(100).regex(/^[a-z][a-z0-9-]*$/),
16
- sourceIdentity: z.string().trim().min(1).max(256),
103
+ sourceIdentity: sourceIdentitySchema,
17
104
  sourceDigest: sha256DigestSchema,
18
- sourceRevision: z.union([
19
- z.string().trim().min(1).max(256),
20
- z.number().int().nonnegative(),
21
- ]),
105
+ sourceRevision: sourceRevisionSchema,
106
+ license: agentSourceLicenseSchema.optional(),
107
+ attribution: sourceStatementListSchema.optional(),
108
+ notices: sourceStatementListSchema.optional(),
109
+ transformations: z
110
+ .array(agentSourceTransformationSchema)
111
+ .min(1)
112
+ .max(128)
113
+ .optional(),
22
114
  })
23
- .strict();
115
+ .strict()
116
+ .superRefine((source, ctx) => {
117
+ const transformations = source.transformations;
118
+ if (transformations === undefined)
119
+ return;
120
+ for (let index = 1; index < transformations.length; index++) {
121
+ if (transformations[index]?.inputDigest !==
122
+ transformations[index - 1]?.outputDigest) {
123
+ ctx.addIssue({
124
+ code: "custom",
125
+ path: ["transformations", index, "inputDigest"],
126
+ message: "transformation input must equal the previous output",
127
+ });
128
+ }
129
+ }
130
+ if (transformations.at(-1)?.outputDigest !== source.sourceDigest) {
131
+ ctx.addIssue({
132
+ code: "custom",
133
+ path: ["sourceDigest"],
134
+ message: "source digest must equal the final transformation output",
135
+ });
136
+ }
137
+ });
24
138
  /** Attach one validated source reference to signed improvement metadata. */
25
139
  export function agentImprovementSourceMetadata(source) {
26
140
  return {
@@ -0,0 +1,41 @@
1
+ import { z } from "zod";
2
+ import type { Sha256Digest } from "./agent-candidate.js";
3
+ /** One exact native file applied before an agent process starts. */
4
+ export interface AgentProfileActivationFileEvidence {
5
+ path: string;
6
+ mode: number;
7
+ content: string;
8
+ }
9
+ /**
10
+ * Shared evidence carried by every exact profile activation.
11
+ *
12
+ * The plan type remains owned by the producer because ordinary agent runs and
13
+ * sealed benchmark runs have different plan contracts. The applied file bytes
14
+ * and activation identity are shared so those producers cannot invent
15
+ * competing activation evidence.
16
+ */
17
+ export interface AgentProfileActivationEvidence<TProfilePlan = unknown> {
18
+ profilePlan: TProfilePlan;
19
+ files: AgentProfileActivationFileEvidence[];
20
+ digest: Sha256Digest;
21
+ }
22
+ /** Runtime validator for one exact native profile file. */
23
+ export declare const agentProfileActivationFileEvidenceSchema: z.ZodObject<{
24
+ path: z.ZodString;
25
+ mode: z.ZodNumber;
26
+ content: z.ZodString;
27
+ }, z.core.$strict>;
28
+ /**
29
+ * Compose the shared activation evidence with a producer-owned exact plan.
30
+ * Candidate materialization uses this factory and adds its stronger plan/file
31
+ * consistency checks around the resulting schema.
32
+ */
33
+ export declare function createAgentProfileActivationEvidenceSchema<TProfilePlan>(profilePlanSchema: z.ZodType<TProfilePlan>): z.ZodObject<{
34
+ profilePlan: z.ZodType<TProfilePlan, unknown, z.core.$ZodTypeInternals<TProfilePlan, unknown>>;
35
+ files: z.ZodArray<z.ZodObject<{
36
+ path: z.ZodString;
37
+ mode: z.ZodNumber;
38
+ content: z.ZodString;
39
+ }, z.core.$strict>>;
40
+ digest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
41
+ }, z.core.$strict>;
@@ -0,0 +1,24 @@
1
+ import { z } from "zod";
2
+ import { isSafeRelativePath, isWellFormedUnicode, sha256DigestSchema, } from "./agent-candidate-schema-common.js";
3
+ /** Runtime validator for one exact native profile file. */
4
+ export const agentProfileActivationFileEvidenceSchema = z.strictObject({
5
+ path: z
6
+ .string()
7
+ .refine((value) => isSafeRelativePath(value, false), "profile activation file must use a canonical relative path"),
8
+ mode: z.number().int().min(0).max(0o777),
9
+ content: z
10
+ .string()
11
+ .refine(isWellFormedUnicode, "profile activation content must be valid Unicode"),
12
+ });
13
+ /**
14
+ * Compose the shared activation evidence with a producer-owned exact plan.
15
+ * Candidate materialization uses this factory and adds its stronger plan/file
16
+ * consistency checks around the resulting schema.
17
+ */
18
+ export function createAgentProfileActivationEvidenceSchema(profilePlanSchema) {
19
+ return z.strictObject({
20
+ profilePlan: profilePlanSchema,
21
+ files: z.array(agentProfileActivationFileEvidenceSchema),
22
+ digest: sha256DigestSchema,
23
+ });
24
+ }
@@ -195,9 +195,31 @@ export declare const agentProfileImprovementExperimentSchema: z.ZodObject<{
195
195
  digestAlgorithm: z.ZodLiteral<"rfc8785-sha256">;
196
196
  source: z.ZodObject<{
197
197
  kind: z.ZodString;
198
- sourceIdentity: z.ZodString;
198
+ sourceIdentity: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
199
199
  sourceDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
200
- sourceRevision: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
200
+ sourceRevision: z.ZodUnion<readonly [z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>, z.ZodNumber]>;
201
+ license: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
202
+ kind: z.ZodLiteral<"spdx">;
203
+ expression: z.ZodString;
204
+ }, z.core.$strict>, z.ZodObject<{
205
+ kind: z.ZodLiteral<"custom">;
206
+ name: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
207
+ reference: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
208
+ termsDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
209
+ }, z.core.$strict>], "kind">>;
210
+ attribution: z.ZodOptional<z.ZodArray<z.ZodString>>;
211
+ notices: z.ZodOptional<z.ZodArray<z.ZodString>>;
212
+ transformations: z.ZodOptional<z.ZodArray<z.ZodObject<{
213
+ kind: z.ZodEnum<{
214
+ normalization: "normalization";
215
+ transformation: "transformation";
216
+ }>;
217
+ identity: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
218
+ revision: z.ZodUnion<readonly [z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>, z.ZodNumber]>;
219
+ procedureDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
220
+ inputDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
221
+ outputDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
222
+ }, z.core.$strict>>>;
201
223
  }, z.core.$strict>;
202
224
  executionRef: z.ZodObject<{
203
225
  identity: z.ZodString;
@@ -702,9 +724,31 @@ export declare const agentProfileImprovementMeasuredComparisonSchema: z.ZodObjec
702
724
  digestAlgorithm: z.ZodLiteral<"rfc8785-sha256">;
703
725
  source: z.ZodObject<{
704
726
  kind: z.ZodString;
705
- sourceIdentity: z.ZodString;
727
+ sourceIdentity: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
706
728
  sourceDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
707
- sourceRevision: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
729
+ sourceRevision: z.ZodUnion<readonly [z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>, z.ZodNumber]>;
730
+ license: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
731
+ kind: z.ZodLiteral<"spdx">;
732
+ expression: z.ZodString;
733
+ }, z.core.$strict>, z.ZodObject<{
734
+ kind: z.ZodLiteral<"custom">;
735
+ name: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
736
+ reference: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
737
+ termsDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
738
+ }, z.core.$strict>], "kind">>;
739
+ attribution: z.ZodOptional<z.ZodArray<z.ZodString>>;
740
+ notices: z.ZodOptional<z.ZodArray<z.ZodString>>;
741
+ transformations: z.ZodOptional<z.ZodArray<z.ZodObject<{
742
+ kind: z.ZodEnum<{
743
+ normalization: "normalization";
744
+ transformation: "transformation";
745
+ }>;
746
+ identity: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
747
+ revision: z.ZodUnion<readonly [z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>, z.ZodNumber]>;
748
+ procedureDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
749
+ inputDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
750
+ outputDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
751
+ }, z.core.$strict>>>;
708
752
  }, z.core.$strict>;
709
753
  executionRef: z.ZodObject<{
710
754
  identity: z.ZodString;
@@ -0,0 +1,34 @@
1
+ import type { AgentProfile } from "./agent-profile.js";
2
+ /**
3
+ * The 29 canonical AgentProfile leaves that can affect one execution.
4
+ *
5
+ * Compound parents such as `model`, `prompt`, and `resources` are deliberately
6
+ * absent. A producer must report the exact requested leaf instead of claiming
7
+ * a parent while silently dropping one of its children.
8
+ */
9
+ export declare const AGENT_PROFILE_MATERIALIZATION_AXES: readonly ["name", "description", "version", "tags", "systemPrompt", "instructions", "modelDefault", "modelSmall", "modelProvider", "modelReasoningEffort", "modelMetadata", "harness", "permissions", "tools", "mcp", "connections", "subagents", "files", "resourceTools", "skills", "resourceAgents", "commands", "resourceInstructions", "resourceFailOnError", "hooks", "modes", "confidential", "metadata", "extensions"];
10
+ /** One exact leaf of the public AgentProfile contract. */
11
+ export type AgentProfileMaterializationAxis = (typeof AGENT_PROFILE_MATERIALIZATION_AXES)[number];
12
+ /** Compatibility name used by runtimes that distinguish canonical axes. */
13
+ export type CanonicalAgentProfileMaterializationAxis = AgentProfileMaterializationAxis;
14
+ /** One requested profile leaf and its canonical RFC 6901 JSON Pointer. */
15
+ export interface AgentProfileMaterializationRequest {
16
+ axis: AgentProfileMaterializationAxis;
17
+ path: string;
18
+ }
19
+ /**
20
+ * Return every canonical profile leaf that contains a meaningful request.
21
+ * Every explicit value is a request, including empty strings, empty
22
+ * collections, `null`, `false`, and `0`. Only an absent/undefined leaf is
23
+ * omitted.
24
+ */
25
+ export declare function profileMaterializationAxes(profile: AgentProfile): readonly AgentProfileMaterializationAxis[];
26
+ /**
27
+ * Expand requested axes into exact JSON Pointer paths.
28
+ *
29
+ * Compound maps and arrays produce one row per explicit scalar leaf. An empty
30
+ * compound value produces its axis-root path. This prevents an executor from
31
+ * acknowledging one tool, server, resource, or instruction while claiming the
32
+ * whole axis, without losing an explicit request to clear that axis.
33
+ */
34
+ export declare function profileMaterializationRequests(profile: AgentProfile): readonly AgentProfileMaterializationRequest[];
@@ -0,0 +1,243 @@
1
+ /**
2
+ * The 29 canonical AgentProfile leaves that can affect one execution.
3
+ *
4
+ * Compound parents such as `model`, `prompt`, and `resources` are deliberately
5
+ * absent. A producer must report the exact requested leaf instead of claiming
6
+ * a parent while silently dropping one of its children.
7
+ */
8
+ export const AGENT_PROFILE_MATERIALIZATION_AXES = [
9
+ "name",
10
+ "description",
11
+ "version",
12
+ "tags",
13
+ "systemPrompt",
14
+ "instructions",
15
+ "modelDefault",
16
+ "modelSmall",
17
+ "modelProvider",
18
+ "modelReasoningEffort",
19
+ "modelMetadata",
20
+ "harness",
21
+ "permissions",
22
+ "tools",
23
+ "mcp",
24
+ "connections",
25
+ "subagents",
26
+ "files",
27
+ "resourceTools",
28
+ "skills",
29
+ "resourceAgents",
30
+ "commands",
31
+ "resourceInstructions",
32
+ "resourceFailOnError",
33
+ "hooks",
34
+ "modes",
35
+ "confidential",
36
+ "metadata",
37
+ "extensions",
38
+ ];
39
+ const profileProperties = [
40
+ "prompt",
41
+ "model",
42
+ "harness",
43
+ "permissions",
44
+ "tools",
45
+ "mcp",
46
+ "connections",
47
+ "subagents",
48
+ "resources",
49
+ "hooks",
50
+ "modes",
51
+ "confidential",
52
+ "metadata",
53
+ "extensions",
54
+ ];
55
+ const profilePropertiesAreExhaustive = true;
56
+ void profilePropertiesAreExhaustive;
57
+ const AXIS_DESCRIPTORS = [
58
+ { axis: "name", rootPath: "/name", value: (profile) => profile.name },
59
+ {
60
+ axis: "description",
61
+ rootPath: "/description",
62
+ value: (profile) => profile.description,
63
+ },
64
+ { axis: "version", rootPath: "/version", value: (profile) => profile.version },
65
+ { axis: "tags", rootPath: "/tags", value: (profile) => profile.tags },
66
+ {
67
+ axis: "systemPrompt",
68
+ rootPath: "/prompt/systemPrompt",
69
+ value: (profile) => profile.prompt?.systemPrompt,
70
+ },
71
+ {
72
+ axis: "instructions",
73
+ rootPath: "/prompt/instructions",
74
+ value: (profile) => profile.prompt?.instructions,
75
+ },
76
+ {
77
+ axis: "modelDefault",
78
+ rootPath: "/model/default",
79
+ value: (profile) => profile.model?.default,
80
+ },
81
+ {
82
+ axis: "modelSmall",
83
+ rootPath: "/model/small",
84
+ value: (profile) => profile.model?.small,
85
+ },
86
+ {
87
+ axis: "modelProvider",
88
+ rootPath: "/model/provider",
89
+ value: (profile) => profile.model?.provider,
90
+ },
91
+ {
92
+ axis: "modelReasoningEffort",
93
+ rootPath: "/model/reasoningEffort",
94
+ value: (profile) => profile.model?.reasoningEffort,
95
+ },
96
+ {
97
+ axis: "modelMetadata",
98
+ rootPath: "/model/metadata",
99
+ value: (profile) => profile.model?.metadata,
100
+ },
101
+ { axis: "harness", rootPath: "/harness", value: (profile) => profile.harness },
102
+ {
103
+ axis: "permissions",
104
+ rootPath: "/permissions",
105
+ value: (profile) => profile.permissions,
106
+ },
107
+ { axis: "tools", rootPath: "/tools", value: (profile) => profile.tools },
108
+ { axis: "mcp", rootPath: "/mcp", value: (profile) => profile.mcp },
109
+ {
110
+ axis: "connections",
111
+ rootPath: "/connections",
112
+ value: (profile) => profile.connections,
113
+ },
114
+ {
115
+ axis: "subagents",
116
+ rootPath: "/subagents",
117
+ value: (profile) => profile.subagents,
118
+ },
119
+ {
120
+ axis: "files",
121
+ rootPath: "/resources/files",
122
+ value: (profile) => profile.resources?.files,
123
+ },
124
+ {
125
+ axis: "resourceTools",
126
+ rootPath: "/resources/tools",
127
+ value: (profile) => profile.resources?.tools,
128
+ },
129
+ {
130
+ axis: "skills",
131
+ rootPath: "/resources/skills",
132
+ value: (profile) => profile.resources?.skills,
133
+ },
134
+ {
135
+ axis: "resourceAgents",
136
+ rootPath: "/resources/agents",
137
+ value: (profile) => profile.resources?.agents,
138
+ },
139
+ {
140
+ axis: "commands",
141
+ rootPath: "/resources/commands",
142
+ value: (profile) => profile.resources?.commands,
143
+ },
144
+ {
145
+ axis: "resourceInstructions",
146
+ rootPath: "/resources/instructions",
147
+ value: (profile) => profile.resources?.instructions,
148
+ },
149
+ {
150
+ axis: "resourceFailOnError",
151
+ rootPath: "/resources/failOnError",
152
+ value: (profile) => profile.resources?.failOnError,
153
+ },
154
+ { axis: "hooks", rootPath: "/hooks", value: (profile) => profile.hooks },
155
+ { axis: "modes", rootPath: "/modes", value: (profile) => profile.modes },
156
+ {
157
+ axis: "confidential",
158
+ rootPath: "/confidential",
159
+ value: (profile) => profile.confidential,
160
+ },
161
+ {
162
+ axis: "metadata",
163
+ rootPath: "/metadata",
164
+ value: (profile) => profile.metadata,
165
+ },
166
+ {
167
+ axis: "extensions",
168
+ rootPath: "/extensions",
169
+ value: (profile) => profile.extensions,
170
+ },
171
+ ];
172
+ const axisDescriptorsAreExhaustive = true;
173
+ void axisDescriptorsAreExhaustive;
174
+ /**
175
+ * Return every canonical profile leaf that contains a meaningful request.
176
+ * Every explicit value is a request, including empty strings, empty
177
+ * collections, `null`, `false`, and `0`. Only an absent/undefined leaf is
178
+ * omitted.
179
+ */
180
+ export function profileMaterializationAxes(profile) {
181
+ const axes = [];
182
+ for (const descriptor of AXIS_DESCRIPTORS) {
183
+ if (descriptor.value(profile) !== undefined) {
184
+ axes.push(descriptor.axis);
185
+ }
186
+ }
187
+ return axes;
188
+ }
189
+ /**
190
+ * Expand requested axes into exact JSON Pointer paths.
191
+ *
192
+ * Compound maps and arrays produce one row per explicit scalar leaf. An empty
193
+ * compound value produces its axis-root path. This prevents an executor from
194
+ * acknowledging one tool, server, resource, or instruction while claiming the
195
+ * whole axis, without losing an explicit request to clear that axis.
196
+ */
197
+ export function profileMaterializationRequests(profile) {
198
+ const requests = [];
199
+ for (const descriptor of AXIS_DESCRIPTORS) {
200
+ const paths = materializationValuePaths(descriptor.value(profile), descriptor.rootPath);
201
+ for (const path of paths) {
202
+ requests.push({ axis: descriptor.axis, path });
203
+ }
204
+ }
205
+ return requests;
206
+ }
207
+ function materializationValuePaths(root, rootPath) {
208
+ const paths = [];
209
+ visitMaterializationValue(root, rootPath, [], paths);
210
+ return paths;
211
+ }
212
+ function visitMaterializationValue(value, path, ancestors, paths) {
213
+ if (value === undefined)
214
+ return false;
215
+ if (value === null || typeof value !== "object") {
216
+ paths.push(path);
217
+ return true;
218
+ }
219
+ if (ancestors.includes(value)) {
220
+ paths.push(path);
221
+ return true;
222
+ }
223
+ const nextAncestors = [...ancestors, value];
224
+ const entries = Array.isArray(value)
225
+ ? Array.from({ length: value.length }, (_, index) => [
226
+ String(index),
227
+ Object.prototype.hasOwnProperty.call(value, index)
228
+ ? value[index]
229
+ : undefined,
230
+ ])
231
+ : Object.entries(value).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0);
232
+ let childRequested = false;
233
+ for (const [key, child] of entries) {
234
+ childRequested =
235
+ visitMaterializationValue(child, `${path}/${escapeJsonPointerSegment(key)}`, nextAncestors, paths) || childRequested;
236
+ }
237
+ if (!childRequested)
238
+ paths.push(path);
239
+ return true;
240
+ }
241
+ function escapeJsonPointerSegment(value) {
242
+ return value.replace(/~/g, "~0").replace(/\//g, "~1");
243
+ }