@tangle-network/agent-interface 0.18.0 → 0.20.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.
@@ -6,6 +6,7 @@
6
6
  * formats internally. This is the canonical home; `@tangle-network/sandbox`
7
7
  * re-exports these symbols for backward compatibility.
8
8
  */
9
+ import type { HarnessType } from "./harness.js";
9
10
  /**
10
11
  * Permission policy value for a capability.
11
12
  */
@@ -230,6 +231,19 @@ export interface AgentProfile {
230
231
  tags?: string[];
231
232
  prompt?: AgentProfilePrompt;
232
233
  model?: AgentProfileModelHints;
234
+ /**
235
+ * Preferred execution harness for this profile — the coding-CLI runtime that
236
+ * materializes and runs it (`claude-code`, `codex`, `opencode`, `pi`, …).
237
+ *
238
+ * This is an optional PREFERENCE, not part of profile IDENTITY: the same
239
+ * profile still runs on any harness, and an executor MAY override it (e.g. the
240
+ * leaderboard's `harness × model` axis sweeps a profile across every harness,
241
+ * and a supervisor spawning a worker may pick a harness per subtask). When
242
+ * unset, the caller/executor chooses. Formalizes what runtimes already read as
243
+ * `profile.harness`; making it typed also lets an improvement loop optimize
244
+ * harness routing as a first-class lever.
245
+ */
246
+ harness?: HarnessType;
233
247
  permissions?: Record<string, AgentProfilePermission>;
234
248
  tools?: Record<string, boolean>;
235
249
  mcp?: Record<string, AgentProfileMcpServer>;
package/dist/harness.d.ts CHANGED
@@ -2,10 +2,13 @@ import { z } from "zod";
2
2
  /**
3
3
  * The execution runner for an agent — WHICH runtime materializes and runs an `AgentProfile`.
4
4
  *
5
- * Harness is an EXECUTION concern chosen by the caller/executor per run, NOT part of the portable
6
- * profile identity: the same `AgentProfile` (prompt/model/skills/tools/mcp/subagents) runs on any
7
- * harness. This is the single shared enum every layer references instead of keeping its own copy
8
- * (session control, the profile materializer, the cli-bridge backends, VB profile specs).
5
+ * Harness is an EXECUTION concern, not part of profile IDENTITY: the same `AgentProfile`
6
+ * (prompt/model/skills/tools/mcp/subagents) runs on any harness. A profile MAY carry an optional
7
+ * `harness` PREFERENCE (`AgentProfile.harness`), but the caller/executor can always override it per
8
+ * run — the leaderboard's `harness × model` axis sweeps one profile across every harness, and a
9
+ * supervisor may pick a harness per spawned worker. This is the single shared enum every layer
10
+ * references instead of keeping its own copy (session control, the profile materializer, the
11
+ * cli-bridge backends, VB profile specs).
9
12
  *
10
13
  * `cli-base` is the router-backed mode — a plain multi-turn router call (a reviewer, a cheap judge,
11
14
  * a one-shot) with no full coding-agent harness. The rest are full agentic harnesses run in a
package/dist/index.d.ts CHANGED
@@ -601,6 +601,7 @@ export interface SdkProviderAdapter {
601
601
  }
602
602
  export * from "./interaction.js";
603
603
  export * from "./agent-profile.js";
604
+ export * from "./profile-diff.js";
604
605
  export * from "./harness.js";
605
606
  export * from "./harness-capabilities.js";
606
607
  export * from "./profile-schema.js";
package/dist/index.js CHANGED
@@ -124,6 +124,7 @@ export function resolveNativeWebTools(tools) {
124
124
  }
125
125
  export * from "./interaction.js";
126
126
  export * from "./agent-profile.js";
127
+ export * from "./profile-diff.js";
127
128
  export * from "./harness.js";
128
129
  export * from "./harness-capabilities.js";
129
130
  export * from "./profile-schema.js";
@@ -0,0 +1,61 @@
1
+ import type { AgentProfile } from "./agent-profile.js";
2
+ export type AgentProfileDiffAxis = "identity" | "prompt" | "model" | "permissions" | "tools" | "mcp" | "connections" | "subagents" | "resources" | "hooks" | "modes" | "confidential" | "metadata" | "extensions";
3
+ export type AgentProfileRemoveList = true | readonly string[];
4
+ export interface AgentProfilePromptRemoval {
5
+ systemPrompt?: true;
6
+ instructions?: AgentProfileRemoveList;
7
+ }
8
+ export interface AgentProfileResourceRemoval {
9
+ files?: AgentProfileRemoveList;
10
+ tools?: AgentProfileRemoveList;
11
+ skills?: AgentProfileRemoveList;
12
+ agents?: AgentProfileRemoveList;
13
+ commands?: AgentProfileRemoveList;
14
+ instructions?: true;
15
+ failOnError?: true;
16
+ }
17
+ export interface AgentProfileDiffRemoval {
18
+ identity?: true;
19
+ tags?: AgentProfileRemoveList;
20
+ prompt?: true | AgentProfilePromptRemoval;
21
+ model?: AgentProfileRemoveList;
22
+ permissions?: AgentProfileRemoveList;
23
+ tools?: AgentProfileRemoveList;
24
+ mcp?: AgentProfileRemoveList;
25
+ connections?: AgentProfileRemoveList;
26
+ subagents?: AgentProfileRemoveList;
27
+ resources?: true | AgentProfileResourceRemoval;
28
+ hooks?: AgentProfileRemoveList;
29
+ modes?: AgentProfileRemoveList;
30
+ confidential?: true;
31
+ metadata?: AgentProfileRemoveList;
32
+ extensions?: AgentProfileRemoveList;
33
+ }
34
+ /**
35
+ * A portable profile improvement artifact.
36
+ *
37
+ * `set` is an AgentProfile overlay: profile arrays are appended with the same
38
+ * semantics as {@link mergeAgentProfiles}. `remove` deletes whole axes or named
39
+ * entries after the overlay is applied. This keeps the optimized unit the full
40
+ * AgentProfile instead of a benchmark-specific file mount.
41
+ */
42
+ export interface AgentProfileDiff {
43
+ schemaVersion: 1;
44
+ kind: "agent-profile-diff";
45
+ id?: string;
46
+ title?: string;
47
+ description?: string;
48
+ rationale?: string;
49
+ source?: {
50
+ kind: "trace" | "frontier-author" | "human" | "optimizer" | "compound";
51
+ artifacts?: readonly string[];
52
+ notes?: readonly string[];
53
+ };
54
+ set?: AgentProfile;
55
+ remove?: AgentProfileDiffRemoval;
56
+ metadata?: Record<string, unknown>;
57
+ }
58
+ export declare function defineAgentProfileDiff<T extends AgentProfileDiff>(diff: T): T;
59
+ export declare function applyAgentProfileDiff(base: AgentProfile, diff: AgentProfileDiff): AgentProfile;
60
+ export declare function changedAgentProfileAxes(diff: AgentProfileDiff): AgentProfileDiffAxis[];
61
+ export declare function pruneAgentProfileDiff(diff: AgentProfileDiff, axesToRemove: readonly AgentProfileDiffAxis[]): AgentProfileDiff;
@@ -0,0 +1,230 @@
1
+ import { mergeAgentProfiles } from "./agent-profile.js";
2
+ export function defineAgentProfileDiff(diff) {
3
+ return diff;
4
+ }
5
+ function asMutable(value) {
6
+ return value ? [...value] : undefined;
7
+ }
8
+ function removeKeys(record, removal) {
9
+ if (!record || removal === undefined)
10
+ return record;
11
+ if (removal === true)
12
+ return undefined;
13
+ const next = {
14
+ ...record,
15
+ };
16
+ for (const key of removal)
17
+ delete next[key];
18
+ return Object.keys(next).length > 0 ? next : undefined;
19
+ }
20
+ function removeValues(values, removal) {
21
+ if (!values || removal === undefined)
22
+ return values;
23
+ if (removal === true)
24
+ return undefined;
25
+ const removeSet = new Set(removal);
26
+ const next = values.filter((value) => !removeSet.has(value));
27
+ return next.length > 0 ? next : undefined;
28
+ }
29
+ function resourceName(resource) {
30
+ return resource.kind === "inline" ? resource.name : resource.name ?? resource.path;
31
+ }
32
+ function removeResourceRefs(refs, removal) {
33
+ if (!refs || removal === undefined)
34
+ return refs;
35
+ if (removal === true)
36
+ return undefined;
37
+ const removeSet = new Set(removal);
38
+ const next = refs.filter((ref) => {
39
+ const name = resourceName(ref);
40
+ return !(name && removeSet.has(name));
41
+ });
42
+ return next.length > 0 ? next : undefined;
43
+ }
44
+ function removeResources(resources, removal) {
45
+ if (!resources || removal === undefined)
46
+ return resources;
47
+ if (removal === true)
48
+ return undefined;
49
+ const next = { ...resources };
50
+ if (removal.files !== undefined) {
51
+ if (removal.files === true) {
52
+ next.files = undefined;
53
+ }
54
+ else {
55
+ const removeSet = new Set(removal.files);
56
+ next.files = next.files?.filter((file) => {
57
+ const name = resourceName(file.resource);
58
+ return !removeSet.has(file.path) && !(name && removeSet.has(name));
59
+ });
60
+ }
61
+ }
62
+ next.tools = removeResourceRefs(next.tools, removal.tools);
63
+ next.skills = removeResourceRefs(next.skills, removal.skills);
64
+ next.agents = removeResourceRefs(next.agents, removal.agents);
65
+ next.commands = removeResourceRefs(next.commands, removal.commands);
66
+ if (removal.instructions)
67
+ next.instructions = undefined;
68
+ if (removal.failOnError)
69
+ next.failOnError = undefined;
70
+ for (const key of [
71
+ "files",
72
+ "tools",
73
+ "skills",
74
+ "agents",
75
+ "commands",
76
+ ]) {
77
+ if (next[key]?.length === 0)
78
+ next[key] = undefined;
79
+ }
80
+ return Object.values(next).some((value) => value !== undefined)
81
+ ? next
82
+ : undefined;
83
+ }
84
+ function applyRemoval(profile, remove) {
85
+ if (!remove)
86
+ return profile;
87
+ const next = { ...profile };
88
+ if (remove.identity) {
89
+ next.name = undefined;
90
+ next.description = undefined;
91
+ next.version = undefined;
92
+ }
93
+ next.tags = removeValues(asMutable(next.tags), remove.tags);
94
+ if (remove.prompt === true) {
95
+ next.prompt = undefined;
96
+ }
97
+ else if (remove.prompt && next.prompt) {
98
+ const prompt = { ...next.prompt };
99
+ if (remove.prompt.systemPrompt)
100
+ prompt.systemPrompt = undefined;
101
+ prompt.instructions = removeValues(prompt.instructions, remove.prompt.instructions);
102
+ next.prompt = Object.values(prompt).some((value) => value !== undefined)
103
+ ? prompt
104
+ : undefined;
105
+ }
106
+ next.model = removeKeys(next.model, remove.model);
107
+ next.permissions = removeKeys(next.permissions, remove.permissions);
108
+ next.tools = removeKeys(next.tools, remove.tools);
109
+ next.mcp = removeKeys(next.mcp, remove.mcp);
110
+ next.subagents = removeKeys(next.subagents, remove.subagents);
111
+ next.resources = removeResources(next.resources, remove.resources);
112
+ next.hooks = removeKeys(next.hooks, remove.hooks);
113
+ next.modes = removeKeys(next.modes, remove.modes);
114
+ if (remove.confidential)
115
+ next.confidential = undefined;
116
+ next.metadata = removeKeys(next.metadata, remove.metadata);
117
+ next.extensions = removeKeys(next.extensions, remove.extensions);
118
+ if (next.connections && remove.connections !== undefined) {
119
+ if (remove.connections === true) {
120
+ next.connections = undefined;
121
+ }
122
+ else {
123
+ const removeSet = new Set(remove.connections);
124
+ const filtered = next.connections.filter((connection) => !removeSet.has(connection.connectionId) &&
125
+ !(connection.alias && removeSet.has(connection.alias)));
126
+ next.connections = filtered.length > 0 ? filtered : undefined;
127
+ }
128
+ }
129
+ return next;
130
+ }
131
+ export function applyAgentProfileDiff(base, diff) {
132
+ const merged = mergeAgentProfiles(base, diff.set) ?? {};
133
+ return applyRemoval(merged, diff.remove);
134
+ }
135
+ export function changedAgentProfileAxes(diff) {
136
+ const axes = new Set();
137
+ const set = diff.set;
138
+ if (set) {
139
+ if (set.name || set.description || set.version || set.tags)
140
+ axes.add("identity");
141
+ for (const axis of [
142
+ "prompt",
143
+ "model",
144
+ "permissions",
145
+ "tools",
146
+ "mcp",
147
+ "connections",
148
+ "subagents",
149
+ "resources",
150
+ "hooks",
151
+ "modes",
152
+ "confidential",
153
+ "metadata",
154
+ "extensions",
155
+ ]) {
156
+ if (set[axis] !== undefined)
157
+ axes.add(axis);
158
+ }
159
+ }
160
+ const remove = diff.remove;
161
+ if (remove) {
162
+ if (remove.identity || remove.tags)
163
+ axes.add("identity");
164
+ for (const axis of [
165
+ "prompt",
166
+ "model",
167
+ "permissions",
168
+ "tools",
169
+ "mcp",
170
+ "connections",
171
+ "subagents",
172
+ "resources",
173
+ "hooks",
174
+ "modes",
175
+ "confidential",
176
+ "metadata",
177
+ "extensions",
178
+ ]) {
179
+ if (remove[axis] !== undefined)
180
+ axes.add(axis);
181
+ }
182
+ }
183
+ return [...axes].sort();
184
+ }
185
+ export function pruneAgentProfileDiff(diff, axesToRemove) {
186
+ const removeSet = new Set(axesToRemove);
187
+ const set = diff.set ? { ...diff.set } : undefined;
188
+ const remove = diff.remove ? { ...diff.remove } : undefined;
189
+ if (removeSet.has("identity") && set) {
190
+ set.name = undefined;
191
+ set.description = undefined;
192
+ set.version = undefined;
193
+ set.tags = undefined;
194
+ }
195
+ if (removeSet.has("identity") && remove) {
196
+ remove.identity = undefined;
197
+ remove.tags = undefined;
198
+ }
199
+ for (const axis of [
200
+ "prompt",
201
+ "model",
202
+ "permissions",
203
+ "tools",
204
+ "mcp",
205
+ "connections",
206
+ "subagents",
207
+ "resources",
208
+ "hooks",
209
+ "modes",
210
+ "confidential",
211
+ "metadata",
212
+ "extensions",
213
+ ]) {
214
+ if (!removeSet.has(axis))
215
+ continue;
216
+ if (set)
217
+ set[axis] = undefined;
218
+ if (remove)
219
+ remove[axis] = undefined;
220
+ }
221
+ return {
222
+ ...diff,
223
+ ...(set && Object.values(set).some((value) => value !== undefined)
224
+ ? { set }
225
+ : { set: undefined }),
226
+ ...(remove && Object.values(remove).some((value) => value !== undefined)
227
+ ? { remove }
228
+ : { remove: undefined }),
229
+ };
230
+ }
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import type { AgentProfile } from "./agent-profile.js";
3
+ import type { AgentProfileDiff } from "./profile-diff.js";
3
4
  import { type SandboxSizePreset } from "./sandbox-size.js";
4
5
  export declare const agentProfilePermissionValueSchema: z.ZodEnum<{
5
6
  allow: "allow";
@@ -199,6 +200,47 @@ export declare const agentProfileConnectionSchema: z.ZodObject<{
199
200
  capabilities: z.ZodArray<z.ZodString>;
200
201
  alias: z.ZodOptional<z.ZodString>;
201
202
  }, z.core.$strip>;
203
+ export declare const agentProfilePromptRemovalSchema: z.ZodObject<{
204
+ systemPrompt: z.ZodOptional<z.ZodLiteral<true>>;
205
+ instructions: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
206
+ }, z.core.$strip>;
207
+ export declare const agentProfileResourceRemovalSchema: z.ZodObject<{
208
+ files: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
209
+ tools: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
210
+ skills: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
211
+ agents: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
212
+ commands: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
213
+ instructions: z.ZodOptional<z.ZodLiteral<true>>;
214
+ failOnError: z.ZodOptional<z.ZodLiteral<true>>;
215
+ }, z.core.$strip>;
216
+ export declare const agentProfileDiffRemovalSchema: z.ZodObject<{
217
+ identity: z.ZodOptional<z.ZodLiteral<true>>;
218
+ tags: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
219
+ prompt: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodObject<{
220
+ systemPrompt: z.ZodOptional<z.ZodLiteral<true>>;
221
+ instructions: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
222
+ }, z.core.$strip>]>>;
223
+ model: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
224
+ permissions: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
225
+ tools: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
226
+ mcp: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
227
+ connections: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
228
+ subagents: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
229
+ resources: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodObject<{
230
+ files: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
231
+ tools: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
232
+ skills: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
233
+ agents: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
234
+ commands: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
235
+ instructions: z.ZodOptional<z.ZodLiteral<true>>;
236
+ failOnError: z.ZodOptional<z.ZodLiteral<true>>;
237
+ }, z.core.$strip>]>>;
238
+ hooks: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
239
+ modes: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
240
+ confidential: z.ZodOptional<z.ZodLiteral<true>>;
241
+ metadata: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
242
+ extensions: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
243
+ }, z.core.$strip>;
202
244
  /**
203
245
  * The complete provider-neutral agent profile schema — the runtime validator for
204
246
  * the canonical {@link AgentProfile} TS contract. Kept structurally in lock-step
@@ -228,6 +270,24 @@ export declare const agentProfileSchema: z.ZodObject<{
228
270
  }>>;
229
271
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
230
272
  }, z.core.$strip>>;
273
+ harness: z.ZodOptional<z.ZodEnum<{
274
+ "claude-code": "claude-code";
275
+ claude: "claude";
276
+ claudish: "claudish";
277
+ nanoclaw: "nanoclaw";
278
+ codex: "codex";
279
+ opencode: "opencode";
280
+ "kimi-code": "kimi-code";
281
+ kimi: "kimi";
282
+ pi: "pi";
283
+ gemini: "gemini";
284
+ hermes: "hermes";
285
+ openclaw: "openclaw";
286
+ amp: "amp";
287
+ "factory-droids": "factory-droids";
288
+ acp: "acp";
289
+ "cli-base": "cli-base";
290
+ }>>;
231
291
  permissions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodEnum<{
232
292
  allow: "allow";
233
293
  ask: "ask";
@@ -380,6 +440,7 @@ export declare const agentProfileSchema: z.ZodObject<{
380
440
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
381
441
  extensions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodUndefined]>>>;
382
442
  }, z.core.$strip>;
443
+ export declare const agentProfileDiffSchema: z.ZodType<AgentProfileDiff>;
383
444
  /**
384
445
  * A registered capability: a stable id paired with its canonical
385
446
  * {@link AgentProfile}. `definition` is the full profile (prompt/model/tools/
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { harnessTypeSchema } from "./harness.js";
2
3
  import { SANDBOX_SIZE_PRESET_NAMES, } from "./sandbox-size.js";
3
4
  export const agentProfilePermissionValueSchema = z.enum([
4
5
  "allow",
@@ -97,6 +98,37 @@ export const agentProfileConnectionSchema = z.object({
97
98
  capabilities: z.array(z.string().min(1)).min(1),
98
99
  alias: z.string().min(1).optional(),
99
100
  });
101
+ const removeListSchema = z.union([z.literal(true), z.array(z.string().min(1))]);
102
+ export const agentProfilePromptRemovalSchema = z.object({
103
+ systemPrompt: z.literal(true).optional(),
104
+ instructions: removeListSchema.optional(),
105
+ });
106
+ export const agentProfileResourceRemovalSchema = z.object({
107
+ files: removeListSchema.optional(),
108
+ tools: removeListSchema.optional(),
109
+ skills: removeListSchema.optional(),
110
+ agents: removeListSchema.optional(),
111
+ commands: removeListSchema.optional(),
112
+ instructions: z.literal(true).optional(),
113
+ failOnError: z.literal(true).optional(),
114
+ });
115
+ export const agentProfileDiffRemovalSchema = z.object({
116
+ identity: z.literal(true).optional(),
117
+ tags: removeListSchema.optional(),
118
+ prompt: z.union([z.literal(true), agentProfilePromptRemovalSchema]).optional(),
119
+ model: removeListSchema.optional(),
120
+ permissions: removeListSchema.optional(),
121
+ tools: removeListSchema.optional(),
122
+ mcp: removeListSchema.optional(),
123
+ connections: removeListSchema.optional(),
124
+ subagents: removeListSchema.optional(),
125
+ resources: z.union([z.literal(true), agentProfileResourceRemovalSchema]).optional(),
126
+ hooks: removeListSchema.optional(),
127
+ modes: removeListSchema.optional(),
128
+ confidential: z.literal(true).optional(),
129
+ metadata: removeListSchema.optional(),
130
+ extensions: removeListSchema.optional(),
131
+ });
100
132
  /**
101
133
  * The complete provider-neutral agent profile schema — the runtime validator for
102
134
  * the canonical {@link AgentProfile} TS contract. Kept structurally in lock-step
@@ -109,6 +141,7 @@ export const agentProfileSchema = z.object({
109
141
  tags: z.array(z.string()).optional(),
110
142
  prompt: agentProfilePromptSchema.optional(),
111
143
  model: agentProfileModelHintsSchema.optional(),
144
+ harness: harnessTypeSchema.optional(),
112
145
  permissions: z.record(z.string(), agentProfilePermissionSchema).optional(),
113
146
  tools: z.record(z.string(), z.boolean()).optional(),
114
147
  mcp: z.record(z.string(), agentProfileMcpServerSchema).optional(),
@@ -125,6 +158,30 @@ export const agentProfileSchema = z.object({
125
158
  .record(z.string(), z.union([z.record(z.string(), z.unknown()), z.undefined()]))
126
159
  .optional(),
127
160
  });
161
+ export const agentProfileDiffSchema = z.object({
162
+ schemaVersion: z.literal(1),
163
+ kind: z.literal("agent-profile-diff"),
164
+ id: z.string().min(1).optional(),
165
+ title: z.string().min(1).optional(),
166
+ description: z.string().optional(),
167
+ rationale: z.string().optional(),
168
+ source: z
169
+ .object({
170
+ kind: z.enum([
171
+ "trace",
172
+ "frontier-author",
173
+ "human",
174
+ "optimizer",
175
+ "compound",
176
+ ]),
177
+ artifacts: z.array(z.string().min(1)).optional(),
178
+ notes: z.array(z.string()).optional(),
179
+ })
180
+ .optional(),
181
+ set: agentProfileSchema.optional(),
182
+ remove: agentProfileDiffRemovalSchema.optional(),
183
+ metadata: z.record(z.string(), z.unknown()).optional(),
184
+ });
128
185
  const _agentProfileSchemaMatchesInterface = true;
129
186
  void _agentProfileSchemaMatchesInterface;
130
187
  export const capabilitySchema = z.object({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-interface",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.js",