@tangle-network/agent-interface 5.3.1 → 5.5.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
  *
@@ -1812,16 +1816,22 @@ export declare function createAgentEnvironmentWithIdempotency<T extends object>(
1812
1816
  /** Reconstruct an existing environment; never allocates a replacement. */
1813
1817
  export interface AgentEnvironmentGetOptions {
1814
1818
  signal?: AbortSignal;
1819
+ /** Side-effect-free custody discovery on a qualified provider. Never resumes, installs or
1820
+ * rebinds; the returned snapshot cannot execute. Unsupported providers must reject this mode.
1821
+ * Expired installed custody may be returned as metadata, never as dispatch authority. */
1822
+ readOnly?: true;
1815
1823
  /** Explicit custody attachment through the existing egress lifecycle. Omission reads current
1816
1824
  * custody; [] revokes custom bindings. A get never allocates a replacement environment. */
1817
1825
  proxySecrets?: readonly ProxySecretBinding[];
1826
+ /** Host-only total destination-to-parent selection; null means explicit independent root. */
1827
+ proxySecretParents?: ProxySecretParents;
1818
1828
  expectedProxySecretGeneration?: number;
1819
1829
  requireInPlace?: boolean;
1820
1830
  /**
1821
1831
  * Authorize the first turn of an accepted portable transfer. The provider looks up the exact
1822
1832
  * durable operation and returns its dispatch-capable environment with contextTransferReceipt.
1823
1833
  * A missing, uncertain, conflicting or unsupported receipt refuses attachment. The request's
1824
- * exact profile, workspace and resources remain authoritative; ordinary get remains read-only.
1834
+ * exact profile, workspace and resources remain authoritative; use readOnly for discovery without reconnect side effects.
1825
1835
  */
1826
1836
  contextTransfer?: ContextTransferRequest;
1827
1837
  }
@@ -1856,6 +1866,7 @@ export declare const AgentEnvironmentGetOptionsSchema: z.ZodObject<{
1856
1866
  }>>;
1857
1867
  ttlSeconds: z.ZodOptional<z.ZodNumber>;
1858
1868
  }, z.core.$strict>>>;
1869
+ proxySecretParents: z.ZodOptional<z.ZodType<Record<string, string | null>, unknown, z.core.$ZodTypeInternals<Record<string, string | null>, unknown>>>;
1859
1870
  contextTransfer: z.ZodOptional<z.ZodObject<{
1860
1871
  operationId: z.ZodString;
1861
1872
  requestDigest: z.ZodType<`sha256:${string}`, unknown, z.core.$ZodTypeInternals<`sha256:${string}`, unknown>>;
@@ -2316,6 +2327,11 @@ export declare const AgentEnvironmentGetOptionsSchema: z.ZodObject<{
2316
2327
  }, z.core.$strict>>;
2317
2328
  }, z.core.$strict>>;
2318
2329
  }, z.core.$strict>;
2330
+ /** Explicit opt-in for providers implementing side-effect-free, non-executable discovery. */
2331
+ export declare const AgentEnvironmentReadOnlyGetOptionsSchema: z.ZodObject<{
2332
+ signal: z.ZodOptional<z.ZodCustom<AbortSignal, AbortSignal>>;
2333
+ readOnly: z.ZodLiteral<true>;
2334
+ }, z.core.$strict>;
2319
2335
  export interface AgentEnvironmentProvider {
2320
2336
  readonly name: string;
2321
2337
  readonly exactProcess?: AgentExactProcessProvider;
@@ -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";
@@ -526,12 +526,20 @@ export async function createAgentEnvironmentWithIdempotency(records, input, crea
526
526
  throw error;
527
527
  }
528
528
  }
529
+ // Keep the existing parser strict: published providers that import it must not silently
530
+ // accept readOnly and then perform their ordinary reconnect side effects.
531
+ const environmentGetSignalSchema = z.custom().optional();
529
532
  export const AgentEnvironmentGetOptionsSchema = z.strictObject({
530
- signal: z.custom().optional(),
533
+ signal: environmentGetSignalSchema,
531
534
  proxySecrets: ProxySecretsSchema.optional(),
535
+ proxySecretParents: ProxySecretParentsSchema.optional(),
532
536
  ...ProxySecretUpdateControlsSchema.shape,
533
537
  contextTransfer: ContextTransferRequestSchema.optional(),
534
538
  }).superRefine((options, ctx) => {
539
+ if (options.proxySecretParents !== undefined &&
540
+ (options.proxySecrets === undefined || !isProxySecretParentsTotal(options.proxySecrets, options.proxySecretParents))) {
541
+ ctx.addIssue({ code: "custom", path: ["proxySecretParents"], message: "parent map requires an explicit total proxySecrets selection" });
542
+ }
535
543
  if (options.proxySecrets !== undefined && options.contextTransfer !== undefined) {
536
544
  ctx.addIssue({ code: "custom", path: ["proxySecrets"], message: "context-transfer attachment cannot also change proxy custody" });
537
545
  }
@@ -540,3 +548,8 @@ export const AgentEnvironmentGetOptionsSchema = z.strictObject({
540
548
  ctx.addIssue({ code: "custom", path: ["proxySecrets"], message: "proxy update controls require an explicit proxySecrets selection" });
541
549
  }
542
550
  });
551
+ /** Explicit opt-in for providers implementing side-effect-free, non-executable discovery. */
552
+ export const AgentEnvironmentReadOnlyGetOptionsSchema = z.strictObject({
553
+ signal: environmentGetSignalSchema,
554
+ readOnly: z.literal(true),
555
+ });
@@ -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.5.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",