@tangle-network/agent-interface 0.37.0 → 0.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-candidate-execution-plan-schema.d.ts +50 -27
- package/dist/agent-candidate-execution-plan-schema.js +4 -16
- package/dist/agent-candidate-profile-schema.d.ts +5 -25
- package/dist/agent-candidate-promotion-schema.d.ts +280 -285
- package/dist/agent-candidate-receipt-schema.d.ts +50 -27
- package/dist/agent-candidate-schema.d.ts +5 -25
- package/dist/agent-candidate.d.ts +2 -8
- package/dist/agent-execution-preparation.d.ts +366 -0
- package/dist/agent-execution-preparation.js +736 -0
- package/dist/agent-profile-activation.d.ts +41 -0
- package/dist/agent-profile-activation.js +24 -0
- package/dist/agent-profile-canonical.d.ts +12 -0
- package/dist/agent-profile-canonical.js +79 -0
- package/dist/agent-profile-improvement-schema.d.ts +3 -6
- package/dist/agent-profile-improvement-schema.js +94 -56
- package/dist/agent-profile-improvement.d.ts +3 -3
- package/dist/agent-profile-materialization.d.ts +34 -0
- package/dist/agent-profile-materialization.js +243 -0
- package/dist/agent-profile.d.ts +44 -7
- package/dist/agent-profile.js +39 -2
- package/dist/agent-workspace-lease.d.ts +138 -0
- package/dist/agent-workspace-lease.js +203 -0
- package/dist/harness-capabilities.d.ts +1 -1
- package/dist/harness-capabilities.js +2 -9
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/profile-diff.d.ts +11 -0
- package/dist/profile-diff.js +123 -3
- package/dist/profile-schema.d.ts +142 -84
- package/dist/profile-schema.js +152 -41
- package/package.json +1 -1
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AgentCandidateJsonValue } from "./agent-candidate.js";
|
|
2
|
+
/**
|
|
3
|
+
* Normalize profile-shaped data into the canonical JSON domain used for public
|
|
4
|
+
* profile identity. Undefined object entries are omitted; unsupported values,
|
|
5
|
+
* sparse arrays, and cycles are rejected with their profile path.
|
|
6
|
+
*
|
|
7
|
+
* This module is intentionally internal. Public callers should use the
|
|
8
|
+
* profile-level operations that own validation, identity, or diff semantics.
|
|
9
|
+
*/
|
|
10
|
+
export declare function canonicalAgentProfileValue(value: unknown): AgentCandidateJsonValue | undefined;
|
|
11
|
+
/** Canonical serialization after applying AgentProfile normalization rules. */
|
|
12
|
+
export declare function canonicalAgentProfileJson(value: unknown): string | undefined;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { canonicalCandidateJson, isWellFormedUnicode, } from "./agent-candidate-schema-common.js";
|
|
2
|
+
/**
|
|
3
|
+
* Normalize profile-shaped data into the canonical JSON domain used for public
|
|
4
|
+
* profile identity. Undefined object entries are omitted; unsupported values,
|
|
5
|
+
* sparse arrays, and cycles are rejected with their profile path.
|
|
6
|
+
*
|
|
7
|
+
* This module is intentionally internal. Public callers should use the
|
|
8
|
+
* profile-level operations that own validation, identity, or diff semantics.
|
|
9
|
+
*/
|
|
10
|
+
export function canonicalAgentProfileValue(value) {
|
|
11
|
+
return normalizeAgentProfileValue(value, [], new Set());
|
|
12
|
+
}
|
|
13
|
+
/** Canonical serialization after applying AgentProfile normalization rules. */
|
|
14
|
+
export function canonicalAgentProfileJson(value) {
|
|
15
|
+
const normalized = canonicalAgentProfileValue(value);
|
|
16
|
+
return normalized === undefined
|
|
17
|
+
? undefined
|
|
18
|
+
: canonicalCandidateJson(normalized);
|
|
19
|
+
}
|
|
20
|
+
function normalizeAgentProfileValue(value, path, ancestors) {
|
|
21
|
+
if (value === undefined)
|
|
22
|
+
return undefined;
|
|
23
|
+
if (value === null ||
|
|
24
|
+
typeof value === "boolean" ||
|
|
25
|
+
typeof value === "string") {
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
if (typeof value === "number") {
|
|
29
|
+
if (!Number.isFinite(value)) {
|
|
30
|
+
throw new Error(`AgentProfile ${renderPath(path)} must be finite`);
|
|
31
|
+
}
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
if (typeof value !== "object") {
|
|
35
|
+
throw new Error(`AgentProfile ${renderPath(path)} is not JSON serializable`);
|
|
36
|
+
}
|
|
37
|
+
if (ancestors.has(value)) {
|
|
38
|
+
throw new Error(`AgentProfile ${renderPath(path)} must be acyclic`);
|
|
39
|
+
}
|
|
40
|
+
const prototype = Object.getPrototypeOf(value);
|
|
41
|
+
if (!Array.isArray(value) &&
|
|
42
|
+
prototype !== Object.prototype &&
|
|
43
|
+
prototype !== null) {
|
|
44
|
+
throw new Error(`AgentProfile ${renderPath(path)} must be a plain JSON object`);
|
|
45
|
+
}
|
|
46
|
+
const nextAncestors = new Set(ancestors).add(value);
|
|
47
|
+
if (Array.isArray(value)) {
|
|
48
|
+
return Array.from({ length: value.length }, (_, index) => {
|
|
49
|
+
if (!Object.prototype.hasOwnProperty.call(value, index)) {
|
|
50
|
+
throw new Error(`AgentProfile ${renderPath([...path, index])} cannot be a sparse array hole`);
|
|
51
|
+
}
|
|
52
|
+
const entry = value[index];
|
|
53
|
+
const normalized = normalizeAgentProfileValue(entry, [...path, index], nextAncestors);
|
|
54
|
+
if (normalized === undefined) {
|
|
55
|
+
throw new Error(`AgentProfile ${renderPath([...path, index])} cannot be undefined`);
|
|
56
|
+
}
|
|
57
|
+
return normalized;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
const material = Object.create(null);
|
|
61
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
62
|
+
if (!isWellFormedUnicode(key)) {
|
|
63
|
+
throw new Error(`AgentProfile ${renderPath(path)} has a record key that is not valid Unicode`);
|
|
64
|
+
}
|
|
65
|
+
const normalized = normalizeAgentProfileValue(entry, [...path, key], nextAncestors);
|
|
66
|
+
if (normalized !== undefined) {
|
|
67
|
+
Object.defineProperty(material, key, {
|
|
68
|
+
value: normalized,
|
|
69
|
+
enumerable: true,
|
|
70
|
+
configurable: true,
|
|
71
|
+
writable: true,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return material;
|
|
76
|
+
}
|
|
77
|
+
function renderPath(path) {
|
|
78
|
+
return path.length === 0 ? "root" : path.join(".");
|
|
79
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import type { AgentImprovementSurface } from "./agent-candidate.js";
|
|
2
3
|
import type { AgentProfileDiff } from "./profile-diff.js";
|
|
3
4
|
export declare const agentProfileImprovementTaskSchema: z.ZodObject<{
|
|
4
5
|
kind: z.ZodLiteral<"agent-profile-improvement-task">;
|
|
@@ -183,11 +184,7 @@ export declare const agentProfileImprovementExecutionRefSchema: z.ZodObject<{
|
|
|
183
184
|
digest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
|
|
184
185
|
kind: z.ZodLiteral<"agent-profile-improvement-execution-ref">;
|
|
185
186
|
}, z.core.$strict>;
|
|
186
|
-
/**
|
|
187
|
-
* The first product path changes only prompt and skills, but it uses the
|
|
188
|
-
* shared profile-diff language so execution and activation apply identical
|
|
189
|
-
* ordered patches.
|
|
190
|
-
*/
|
|
187
|
+
/** One strict canonical profile patch in an ordered measured change. */
|
|
191
188
|
export declare const agentProfileImprovementChangeStepSchema: z.ZodType<AgentProfileDiff, unknown, z.core.$ZodTypeInternals<AgentProfileDiff, unknown>>;
|
|
192
189
|
export declare const agentProfileImprovementChangeSchema: z.ZodTuple<[z.ZodType<AgentProfileDiff, unknown, z.core.$ZodTypeInternals<AgentProfileDiff, unknown>>], z.ZodType<AgentProfileDiff, unknown, z.core.$ZodTypeInternals<AgentProfileDiff, unknown>>>;
|
|
193
190
|
export declare const agentProfileImprovementExperimentSchema: z.ZodObject<{
|
|
@@ -1208,4 +1205,4 @@ export declare const agentProfileImprovementMeasuredComparisonSchema: z.ZodObjec
|
|
|
1208
1205
|
}, z.core.$strict>;
|
|
1209
1206
|
}, z.core.$strict>>;
|
|
1210
1207
|
}, z.core.$strict>;
|
|
1211
|
-
export declare function changedProfileImprovementSurfaces(change: readonly AgentProfileDiff[]):
|
|
1208
|
+
export declare function changedProfileImprovementSurfaces(change: readonly AgentProfileDiff[]): AgentImprovementSurface[];
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { changedAgentProfileAxes } from "./profile-diff.js";
|
|
2
3
|
import { agentCandidateLineageSchema } from "./agent-candidate-lineage-schema.js";
|
|
3
4
|
import { canonicalCandidateDigest, isCanonicalJsonValue, omitTopLevelDigest, sha256DigestSchema, } from "./agent-candidate-schema-common.js";
|
|
4
5
|
import { refineAgentExecutionWithinLimits } from "./agent-execution-limits.js";
|
|
@@ -103,67 +104,48 @@ export const agentProfileImprovementExecutionRefSchema = profileImprovementEvide
|
|
|
103
104
|
kind: z.literal("agent-profile-improvement-execution-ref"),
|
|
104
105
|
})
|
|
105
106
|
.strict();
|
|
106
|
-
/**
|
|
107
|
-
* The first product path changes only prompt and skills, but it uses the
|
|
108
|
-
* shared profile-diff language so execution and activation apply identical
|
|
109
|
-
* ordered patches.
|
|
110
|
-
*/
|
|
107
|
+
/** One strict canonical profile patch in an ordered measured change. */
|
|
111
108
|
export const agentProfileImprovementChangeStepSchema = agentProfileDiffSchema.superRefine((change, ctx) => {
|
|
112
109
|
const changed = changedProfileImprovementSurfaces([change]);
|
|
113
110
|
if (changed.length === 0) {
|
|
114
111
|
ctx.addIssue({
|
|
115
112
|
code: "custom",
|
|
116
|
-
message: "profile improvement patch must change
|
|
113
|
+
message: "profile improvement patch must change the agent profile",
|
|
117
114
|
});
|
|
118
115
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const removeKeys = Object.keys(change.remove ?? {});
|
|
143
|
-
if (removeKeys.some((key) => key !== "prompt" && key !== "resources")) {
|
|
144
|
-
ctx.addIssue({
|
|
145
|
-
code: "custom",
|
|
146
|
-
path: ["remove"],
|
|
147
|
-
message: "profile improvement patches may remove only prompt or skill resources",
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
if (change.remove?.resources === true) {
|
|
151
|
-
ctx.addIssue({
|
|
152
|
-
code: "custom",
|
|
153
|
-
path: ["remove", "resources"],
|
|
154
|
-
message: "profile improvement patches may not remove unrelated resources",
|
|
155
|
-
});
|
|
116
|
+
refineInlineProfileImprovementResources(change, ctx);
|
|
117
|
+
});
|
|
118
|
+
function refineInlineProfileImprovementResources(change, ctx) {
|
|
119
|
+
const resources = change.set?.resources;
|
|
120
|
+
if (resources === undefined)
|
|
121
|
+
return;
|
|
122
|
+
const groups = [
|
|
123
|
+
["files", resources.files?.map((file) => file.resource)],
|
|
124
|
+
["tools", resources.tools],
|
|
125
|
+
["skills", resources.skills],
|
|
126
|
+
["agents", resources.agents],
|
|
127
|
+
["commands", resources.commands],
|
|
128
|
+
];
|
|
129
|
+
for (const [name, refs] of groups) {
|
|
130
|
+
for (const [index, ref] of (refs ?? []).entries()) {
|
|
131
|
+
if (ref.kind !== "inline") {
|
|
132
|
+
ctx.addIssue({
|
|
133
|
+
code: "custom",
|
|
134
|
+
path: ["set", "resources", name, index],
|
|
135
|
+
message: "measured profile resource patches require inline content with exact bytes",
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
156
139
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
if (removeResourceKeys.some((key) => key !== "skills")) {
|
|
140
|
+
if (typeof resources.instructions === "object" &&
|
|
141
|
+
resources.instructions.kind !== "inline") {
|
|
160
142
|
ctx.addIssue({
|
|
161
143
|
code: "custom",
|
|
162
|
-
path: ["
|
|
163
|
-
message: "profile
|
|
144
|
+
path: ["set", "resources", "instructions"],
|
|
145
|
+
message: "measured profile resource patches require inline content with exact bytes",
|
|
164
146
|
});
|
|
165
147
|
}
|
|
166
|
-
}
|
|
148
|
+
}
|
|
167
149
|
export const agentProfileImprovementChangeSchema = z
|
|
168
150
|
.tuple([agentProfileImprovementChangeStepSchema])
|
|
169
151
|
.rest(agentProfileImprovementChangeStepSchema)
|
|
@@ -420,16 +402,72 @@ export const agentProfileImprovementMeasuredComparisonSchema = z
|
|
|
420
402
|
export function changedProfileImprovementSurfaces(change) {
|
|
421
403
|
const surfaces = new Set();
|
|
422
404
|
for (const step of change) {
|
|
423
|
-
|
|
424
|
-
|
|
405
|
+
for (const axis of changedAgentProfileAxes(step)) {
|
|
406
|
+
if (axis === "prompt" ||
|
|
407
|
+
axis === "tools" ||
|
|
408
|
+
axis === "mcp" ||
|
|
409
|
+
axis === "hooks" ||
|
|
410
|
+
axis === "subagents") {
|
|
411
|
+
surfaces.add(axis);
|
|
412
|
+
}
|
|
413
|
+
else if (axis === "resources") {
|
|
414
|
+
const resources = changedResourceSurfaces(step);
|
|
415
|
+
for (const surface of resources.granular)
|
|
416
|
+
surfaces.add(surface);
|
|
417
|
+
if (resources.other)
|
|
418
|
+
surfaces.add("agent-profile");
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
surfaces.add("agent-profile");
|
|
422
|
+
}
|
|
425
423
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
424
|
+
}
|
|
425
|
+
const canonicalOrder = [
|
|
426
|
+
"prompt",
|
|
427
|
+
"skills",
|
|
428
|
+
"tools",
|
|
429
|
+
"mcp",
|
|
430
|
+
"hooks",
|
|
431
|
+
"subagents",
|
|
432
|
+
"agent-profile",
|
|
433
|
+
];
|
|
434
|
+
return canonicalOrder.filter((surface) => surfaces.has(surface));
|
|
435
|
+
}
|
|
436
|
+
function changedResourceSurfaces(change) {
|
|
437
|
+
const granular = new Set();
|
|
438
|
+
let other = false;
|
|
439
|
+
const setResources = change.set?.resources;
|
|
440
|
+
if (setResources !== undefined) {
|
|
441
|
+
const keys = Object.keys(setResources);
|
|
442
|
+
for (const key of keys) {
|
|
443
|
+
if (key === "skills" || key === "tools")
|
|
444
|
+
granular.add(key);
|
|
445
|
+
else if (key === "agents")
|
|
446
|
+
granular.add("subagents");
|
|
447
|
+
else
|
|
448
|
+
other = true;
|
|
449
|
+
}
|
|
450
|
+
other ||= keys.length === 0;
|
|
451
|
+
}
|
|
452
|
+
const removeResources = change.remove?.resources;
|
|
453
|
+
if (removeResources === true) {
|
|
454
|
+
granular.add("skills");
|
|
455
|
+
granular.add("tools");
|
|
456
|
+
granular.add("subagents");
|
|
457
|
+
other = true;
|
|
458
|
+
}
|
|
459
|
+
else if (removeResources !== undefined) {
|
|
460
|
+
const entries = Object.entries(removeResources).filter(([, value]) => Array.isArray(value) ? value.length > 0 : value === true);
|
|
461
|
+
for (const [key] of entries) {
|
|
462
|
+
if (key === "skills" || key === "tools")
|
|
463
|
+
granular.add(key);
|
|
464
|
+
else if (key === "agents")
|
|
465
|
+
granular.add("subagents");
|
|
466
|
+
else
|
|
467
|
+
other = true;
|
|
430
468
|
}
|
|
431
469
|
}
|
|
432
|
-
return
|
|
470
|
+
return { granular, other };
|
|
433
471
|
}
|
|
434
472
|
function refineProfileImprovementComparison(comparison, ctx) {
|
|
435
473
|
const { suite, tasks } = comparison.experiment.benchmark;
|
|
@@ -52,9 +52,9 @@ export interface AgentProfileImprovementExecutionRef extends AgentProfileImprove
|
|
|
52
52
|
* Ordered portable profile patches retained for review and activation.
|
|
53
53
|
*
|
|
54
54
|
* Applying the steps in order matters: a full resource replacement is a reset
|
|
55
|
-
* followed by a replacement step.
|
|
56
|
-
*
|
|
57
|
-
* redaction.
|
|
55
|
+
* followed by a replacement step. Complete profile diffs can contain sensitive
|
|
56
|
+
* host-owned configuration, so the product that persists this value owns access
|
|
57
|
+
* control and redaction.
|
|
58
58
|
*/
|
|
59
59
|
export type AgentProfileImprovementChange = [AgentProfileDiff, ...AgentProfileDiff[]];
|
|
60
60
|
/** A measured comparison of two states of one host-owned agent profile. */
|
|
@@ -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
|
+
}
|