@tangle-network/agent-interface 5.3.1 → 5.4.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.
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { type ProxySecretBinding, type ProxySecretCapabilities, type ProxySecretReceipt } from "./proxy-secrets.js";
2
+ import { type ProxySecretBinding, type ProxySecretCapabilities, type ProxySecretReceipt, type ProxySecretParents } from "./proxy-secrets.js";
3
3
  import type { AgentRuntimeAttachments } from "./runtime-attachments.js";
4
4
  export { AgentRuntimeAttachmentsSchema, type AgentRuntimeAttachments } from "./runtime-attachments.js";
5
5
  import type { AgentCandidateArtifactPort, Sha256Digest } from "./agent-candidate.js";
@@ -1321,6 +1321,8 @@ export interface AgentEnvironment {
1321
1321
  readonly contextTransferReceipt?: ContextTransferReceipt;
1322
1322
  /** Trusted metadata only; dispatch requires an installed receipt, never proxy-installed. */
1323
1323
  readonly proxySecretReceipt?: ProxySecretReceipt;
1324
+ /** API-verified effective parent pins read from current custody. */
1325
+ readonly proxySecretParents?: ProxySecretParents;
1324
1326
  /**
1325
1327
  * Detached metadata returned by the provider.
1326
1328
  * It can contain caller-authored annotations and is not authorization evidence.
@@ -1738,6 +1740,8 @@ export interface CreateAgentEnvironmentInput {
1738
1740
  /** Same declaration as AgentProfile. Empty selections remain explicit wire values.
1739
1741
  * Trusted issuer authorization is required before resolving any reference. */
1740
1742
  proxySecrets?: readonly ProxySecretBinding[];
1743
+ /** Host-only total destination-to-parent selection; null means explicit independent root. */
1744
+ proxySecretParents?: ProxySecretParents;
1741
1745
  /**
1742
1746
  * Outbound network policy for this environment.
1743
1747
  *
@@ -1815,6 +1819,8 @@ export interface AgentEnvironmentGetOptions {
1815
1819
  /** Explicit custody attachment through the existing egress lifecycle. Omission reads current
1816
1820
  * custody; [] revokes custom bindings. A get never allocates a replacement environment. */
1817
1821
  proxySecrets?: readonly ProxySecretBinding[];
1822
+ /** Host-only total destination-to-parent selection; null means explicit independent root. */
1823
+ proxySecretParents?: ProxySecretParents;
1818
1824
  expectedProxySecretGeneration?: number;
1819
1825
  requireInPlace?: boolean;
1820
1826
  /**
@@ -1856,6 +1862,7 @@ export declare const AgentEnvironmentGetOptionsSchema: z.ZodObject<{
1856
1862
  }>>;
1857
1863
  ttlSeconds: z.ZodOptional<z.ZodNumber>;
1858
1864
  }, z.core.$strict>>>;
1865
+ proxySecretParents: z.ZodOptional<z.ZodType<Record<string, string | null>, unknown, z.core.$ZodTypeInternals<Record<string, string | null>, unknown>>>;
1859
1866
  contextTransfer: z.ZodOptional<z.ZodObject<{
1860
1867
  operationId: z.ZodString;
1861
1868
  requestDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { ProxySecretCapabilitiesSchema, ProxySecretsSchema, ProxySecretUpdateControlsSchema } from "./proxy-secrets.js";
2
+ import { ProxySecretCapabilitiesSchema, ProxySecretParentsSchema, isProxySecretParentsTotal, ProxySecretsSchema, ProxySecretUpdateControlsSchema } from "./proxy-secrets.js";
3
3
  export { AgentRuntimeAttachmentsSchema } from "./runtime-attachments.js";
4
4
  import { canonicalCandidateDigest, canonicalCandidateJson, } from "./agent-candidate-schema-common.js";
5
5
  import { agentProfileSchema } from "./profile-schema.js";
@@ -529,9 +529,14 @@ export async function createAgentEnvironmentWithIdempotency(records, input, crea
529
529
  export const AgentEnvironmentGetOptionsSchema = z.strictObject({
530
530
  signal: z.custom().optional(),
531
531
  proxySecrets: ProxySecretsSchema.optional(),
532
+ proxySecretParents: ProxySecretParentsSchema.optional(),
532
533
  ...ProxySecretUpdateControlsSchema.shape,
533
534
  contextTransfer: ContextTransferRequestSchema.optional(),
534
535
  }).superRefine((options, ctx) => {
536
+ if (options.proxySecretParents !== undefined &&
537
+ (options.proxySecrets === undefined || !isProxySecretParentsTotal(options.proxySecrets, options.proxySecretParents))) {
538
+ ctx.addIssue({ code: "custom", path: ["proxySecretParents"], message: "parent map requires an explicit total proxySecrets selection" });
539
+ }
535
540
  if (options.proxySecrets !== undefined && options.contextTransfer !== undefined) {
536
541
  ctx.addIssue({ code: "custom", path: ["proxySecrets"], message: "context-transfer attachment cannot also change proxy custody" });
537
542
  }
@@ -0,0 +1,9 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Zod records currently assign parsed values onto an ordinary object. The
4
+ * special own key `__proto__` therefore invokes the legacy prototype setter
5
+ * and disappears instead of being validated. Encode every own key before Zod
6
+ * sees it, then restore the exact UTF-16 key with defineProperty so all string
7
+ * keys allowed by `Record<string, ...>` remain data rather than object syntax.
8
+ */
9
+ export declare function ownPropertyRecordSchema<ValueSchema extends z.ZodType>(valueSchema: ValueSchema): z.ZodType<Record<string, z.output<ValueSchema>>>;
@@ -0,0 +1,52 @@
1
+ import { z } from "zod";
2
+ import { isWellFormedUnicode } from "./agent-candidate-schema-common.js";
3
+ /**
4
+ * Zod records currently assign parsed values onto an ordinary object. The
5
+ * special own key `__proto__` therefore invokes the legacy prototype setter
6
+ * and disappears instead of being validated. Encode every own key before Zod
7
+ * sees it, then restore the exact UTF-16 key with defineProperty so all string
8
+ * keys allowed by `Record<string, ...>` remain data rather than object syntax.
9
+ */
10
+ export function ownPropertyRecordSchema(valueSchema) {
11
+ return z.preprocess(encodeOwnRecordKeys, z.record(z
12
+ .string()
13
+ .regex(/^u(?:[0-9a-f]{4})*$/, "record keys must contain valid Unicode"), valueSchema).transform((record) => {
14
+ const restored = {};
15
+ for (const [encodedKey, value] of Object.entries(record)) {
16
+ Object.defineProperty(restored, decodeRecordKey(encodedKey), {
17
+ value,
18
+ enumerable: true,
19
+ configurable: true,
20
+ writable: true,
21
+ });
22
+ }
23
+ return restored;
24
+ }));
25
+ }
26
+ function encodeOwnRecordKeys(value) {
27
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
28
+ return value;
29
+ }
30
+ const prototype = Object.getPrototypeOf(value);
31
+ if (prototype !== Object.prototype && prototype !== null)
32
+ return [];
33
+ const encoded = Object.create(null);
34
+ for (const [key, entry] of Object.entries(value)) {
35
+ encoded[encodeRecordKey(key)] = entry;
36
+ }
37
+ return encoded;
38
+ }
39
+ function encodeRecordKey(value) {
40
+ let encoded = isWellFormedUnicode(value) ? "u" : "i";
41
+ for (let index = 0; index < value.length; index += 1) {
42
+ encoded += value.charCodeAt(index).toString(16).padStart(4, "0");
43
+ }
44
+ return encoded;
45
+ }
46
+ function decodeRecordKey(value) {
47
+ let decoded = "";
48
+ for (let index = 1; index < value.length; index += 4) {
49
+ decoded += String.fromCharCode(Number.parseInt(value.slice(index, index + 4), 16));
50
+ }
51
+ return decoded;
52
+ }
@@ -1,5 +1,6 @@
1
1
  import { agentCandidateSecretRefSchema } from "./agent-candidate-schema-common.js";
2
2
  import { z } from "zod";
3
+ import { ownPropertyRecordSchema } from "./own-property-record.js";
3
4
  import { ProxySecretsSchema } from "./proxy-secrets.js";
4
5
  import { agentProfileKnowledgeRefsSchema } from "./profile-knowledge.js";
5
6
  export { agentProfileKnowledgeRefSchema, agentProfileKnowledgeRefsSchema, } from "./profile-knowledge.js";
@@ -9,53 +10,6 @@ import { harnessTypeSchema } from "./harness.js";
9
10
  import { canonicalAgentProfileJson } from "./agent-profile-canonical.js";
10
11
  import { harnessHonorsEffort, harnessHonorsModel, harnessModelSupport, harnessReasoningEfforts, harnessSystemPromptIntents, resolveModelProvider, } from "./harness-capabilities.js";
11
12
  import { SANDBOX_SIZE_PRESET_NAMES, } from "./sandbox-size.js";
12
- /**
13
- * Zod records currently assign parsed values onto an ordinary object. The
14
- * special own key `__proto__` therefore invokes the legacy prototype setter
15
- * and disappears instead of being validated. Encode every own key before Zod
16
- * sees it, then restore the exact UTF-16 key with defineProperty so all string
17
- * keys allowed by `Record<string, ...>` remain data rather than object syntax.
18
- */
19
- function ownPropertyRecordSchema(valueSchema) {
20
- return z.preprocess(encodeOwnRecordKeys, z.record(z
21
- .string()
22
- .regex(/^u(?:[0-9a-f]{4})*$/, "record keys must contain valid Unicode"), valueSchema).transform((record) => {
23
- const restored = {};
24
- for (const [encodedKey, value] of Object.entries(record)) {
25
- Object.defineProperty(restored, decodeRecordKey(encodedKey), {
26
- value,
27
- enumerable: true,
28
- configurable: true,
29
- writable: true,
30
- });
31
- }
32
- return restored;
33
- }));
34
- }
35
- function encodeOwnRecordKeys(value) {
36
- if (value === null || typeof value !== "object" || Array.isArray(value)) {
37
- return value;
38
- }
39
- const encoded = Object.create(null);
40
- for (const [key, entry] of Object.entries(value)) {
41
- encoded[encodeRecordKey(key)] = entry;
42
- }
43
- return encoded;
44
- }
45
- function encodeRecordKey(value) {
46
- let encoded = isWellFormedUnicode(value) ? "u" : "i";
47
- for (let index = 0; index < value.length; index += 1) {
48
- encoded += value.charCodeAt(index).toString(16).padStart(4, "0");
49
- }
50
- return encoded;
51
- }
52
- function decodeRecordKey(value) {
53
- let decoded = "";
54
- for (let index = 1; index < value.length; index += 4) {
55
- decoded += String.fromCharCode(Number.parseInt(value.slice(index, index + 4), 16));
56
- }
57
- return decoded;
58
- }
59
13
  export const agentProfilePermissionValueSchema = z.enum([
60
14
  "allow",
61
15
  "deny",
@@ -81,6 +81,16 @@ export declare const ProxySecretsSchema: z.ZodArray<z.ZodObject<{
81
81
  }>>;
82
82
  ttlSeconds: z.ZodOptional<z.ZodNumber>;
83
83
  }, z.core.$strict>>;
84
+ /** Host execution control, never part of an authored declaration or profile identity.
85
+ * Strings select an API-verified parent sandbox; null explicitly selects independent issuance.
86
+ * When present, every destination in the final effective selection must have exactly one key.
87
+ */
88
+ export declare const ProxySecretParentsSchema: z.ZodType<Record<string, string | null>, unknown, z.core.$ZodTypeInternals<Record<string, string | null>, unknown>>;
89
+ export type ProxySecretParents = z.infer<typeof ProxySecretParentsSchema>;
90
+ /** Shape and totality only; the API verifies issuer authority and durable immutable pins. */
91
+ export declare function isProxySecretParentsTotal(bindings: readonly ProxySecretBinding[], parents: unknown): parents is ProxySecretParents;
92
+ /** API control-plane support; intentionally separate from the engine capability contract. */
93
+ export declare const ProxySecretDelegationCapabilitySchema: z.ZodLiteral<1>;
84
94
  export declare const ProxySecretResolvedIdentitySchema: z.ZodObject<{
85
95
  tenantId: z.ZodString;
86
96
  issuerId: z.ZodString;
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { ownPropertyRecordSchema } from "./own-property-record.js";
2
3
  import { agentCandidateSecretRefSchema } from "./agent-candidate-schema-common.js";
3
4
  import { boundedIdentifierSchema, CONTRACT_MAX_ARRAY_LENGTH } from "./contract-limits.js";
4
5
  /**
@@ -52,6 +53,22 @@ export const ProxySecretBindingSchema = ProxySecretScopeSchema.extend({
52
53
  });
53
54
  export const ProxySecretsSchema = z.array(ProxySecretBindingSchema).max(CONTRACT_MAX_ARRAY_LENGTH)
54
55
  .refine((bindings) => unique(bindings.map((binding) => binding.envName)), "proxy secret env names must be unique");
56
+ /** Host execution control, never part of an authored declaration or profile identity.
57
+ * Strings select an API-verified parent sandbox; null explicitly selects independent issuance.
58
+ * When present, every destination in the final effective selection must have exactly one key.
59
+ */
60
+ export const ProxySecretParentsSchema = ownPropertyRecordSchema(boundedIdentifierSchema.nullable())
61
+ .refine((parents) => Object.keys(parents).length <= CONTRACT_MAX_ARRAY_LENGTH &&
62
+ Object.keys(parents).every((name) => envNameSchema.safeParse(name).success), "invalid parent selection keys");
63
+ /** Shape and totality only; the API verifies issuer authority and durable immutable pins. */
64
+ export function isProxySecretParentsTotal(bindings, parents) {
65
+ const selection = ProxySecretsSchema.safeParse(bindings);
66
+ const parsed = ProxySecretParentsSchema.safeParse(parents);
67
+ return selection.success && parsed.success && Object.keys(parsed.data).length === selection.data.length &&
68
+ selection.data.every((binding) => Object.hasOwn(parsed.data, binding.envName));
69
+ }
70
+ /** API control-plane support; intentionally separate from the engine capability contract. */
71
+ export const ProxySecretDelegationCapabilitySchema = z.literal(1);
55
72
  export const ProxySecretResolvedIdentitySchema = z.strictObject({
56
73
  tenantId: boundedIdentifierSchema, issuerId: boundedIdentifierSchema,
57
74
  secretId: boundedIdentifierSchema, revision: boundedIdentifierSchema,
@@ -1169,5 +1169,72 @@
1169
1169
  "placeholder": "synthetic non-secret bytes, scoped only to this case",
1170
1170
  "authority": "SNI and authority must identify declared FQDN; omitted port and explicit :443 equivalent",
1171
1171
  "paths": "all percent-encoded request paths refused in v1"
1172
- }
1172
+ },
1173
+ "parents": [
1174
+ {
1175
+ "name": "mixed-authority",
1176
+ "envNames": [
1177
+ "RENAMED_TOKEN",
1178
+ "COORD"
1179
+ ],
1180
+ "value": {
1181
+ "RENAMED_TOKEN": "parent-sandbox",
1182
+ "COORD": null
1183
+ },
1184
+ "valid": true
1185
+ },
1186
+ {
1187
+ "name": "missing-destination",
1188
+ "envNames": [
1189
+ "RENAMED_TOKEN",
1190
+ "COORD"
1191
+ ],
1192
+ "value": {
1193
+ "RENAMED_TOKEN": "parent-sandbox"
1194
+ },
1195
+ "valid": false
1196
+ },
1197
+ {
1198
+ "name": "extra-destination",
1199
+ "envNames": [
1200
+ "RENAMED_TOKEN"
1201
+ ],
1202
+ "value": {
1203
+ "RENAMED_TOKEN": "parent-sandbox",
1204
+ "COORD": null
1205
+ },
1206
+ "valid": false
1207
+ },
1208
+ {
1209
+ "name": "forbidden-env-selector",
1210
+ "envNames": [
1211
+ "RENAMED_TOKEN"
1212
+ ],
1213
+ "value": {
1214
+ "RENAMED_TOKEN": {
1215
+ "sandboxId": "parent-sandbox",
1216
+ "envName": "ORIGINAL_TOKEN"
1217
+ }
1218
+ },
1219
+ "valid": false
1220
+ },
1221
+ {
1222
+ "name": "forbidden-grant-id",
1223
+ "envNames": [
1224
+ "RENAMED_TOKEN"
1225
+ ],
1226
+ "value": {
1227
+ "RENAMED_TOKEN": {
1228
+ "grantId": "grant-parent"
1229
+ }
1230
+ },
1231
+ "valid": false
1232
+ },
1233
+ {
1234
+ "name": "empty-revoke",
1235
+ "envNames": [],
1236
+ "value": {},
1237
+ "valid": true
1238
+ }
1239
+ ]
1173
1240
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-interface",
3
- "version": "5.3.1",
3
+ "version": "5.4.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",