@agent-surface/core 0.15.0 → 0.16.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/README.md CHANGED
@@ -1,49 +1,22 @@
1
- # @agent-surface/core
1
+ # `@agent-surface/core`
2
2
 
3
- Framework-agnostic core of [agent-surface](https://github.com/Wiseair-srl/agent-surface): a registry for declaring an explicit, semantic, typed, policy-governed *agent surface* over a frontend — and nothing more. If a component or capability is not explicitly annotated, it does not exist for the agent.
4
-
5
- Zero runtime dependencies. Provides: canonical capability ids, the `AgentSchema` layer (Standard Schema + built-in JSON Schema subset validator), component/capability definitions, the registry (registration lifecycle, availability, versioning, staleness), synchronous snapshots, the 10-phase invocation pipeline, composable policies, single-use confirmation evidence, audit sinks, and a provider-neutral toolset projection for embedded agent loops.
6
-
7
- Docs: https://agent-surface-docs.vercel.app
8
-
9
- ## Install
10
-
11
- ```bash
12
- pnpm add @agent-surface/core
13
- ```
14
-
15
- ## Use
3
+ Framework-neutral contracts, registry, policy, confirmation, invocation and exposure gateway.
16
4
 
17
5
  ```ts
18
- import {
19
- createAgentSurfaceRegistry,
20
- defineAgentComponent,
21
- observation,
22
- action,
23
- fromStandardSchema,
24
- createAgentToolset,
25
- } from "@agent-surface/core";
26
-
27
- const registry = createAgentSurfaceRegistry({
28
- environment: import.meta.env.DEV ? "development" : "production",
29
- context: () => ({ user: authStore.user }),
6
+ const contract = defineAgentComponentContract({
7
+ type: "devices.table",
8
+ description: "Device table",
9
+ observations: { readState: observationContract({ description: "State", output }) },
10
+ actions: { selectRows: actionContract({ description: "Select", input, effect: "local-state" }) },
30
11
  });
31
12
 
32
- registry.register(
33
- defineAgentComponent({
34
- type: "devices.table",
35
- description: "Table of the devices visible on the current page",
36
- observations: { readState: observation({ /* … */ }) },
37
- actions: { selectRows: action({ /* … */ }) },
38
- }),
39
- );
40
-
41
- const toolset = createAgentToolset(registry, {
42
- consumer: { id: "copilot", kind: "embedded" },
43
- topology: "embedded", // required (D26): embedded → confirmations "wait",
44
- }); // remote → "two-phase". No global default.
13
+ const registry = createAgentSurfaceRegistry({ manifest });
14
+ registry.register(contract.bind({
15
+ observations: { readState: { read } },
16
+ actions: { selectRows: { execute } },
17
+ }));
45
18
  ```
46
19
 
47
- React apps should use [`@agent-surface/react`](https://www.npmjs.com/package/@agent-surface/react) instead of calling `register` directly. Full specification: [docs](https://github.com/Wiseair-srl/agent-surface/tree/main/docs).
20
+ With a compiler manifest installed, raw/unknown/stale/mismatched registrations fail closed. Use `createAgentExposureGateway()` at final provider/MCP assembly.
48
21
 
49
- MIT © Wiseair S.r.l.
22
+ See [Core API](../../docs/03-core-api.md).
package/dist/explain.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { D as DiscoveryDecision, A as AgentRouteInfo, a as AgentConsumer, b as AgentSurfaceRegistry, S as SnapshotContext } from './registry-XD1QsGQ4.js';
2
- export { m as matchesScope } from './registry-XD1QsGQ4.js';
1
+ import { D as DiscoveryDecision, A as AgentRouteInfo, a as AgentConsumer, b as AgentSurfaceRegistry, S as SnapshotContext } from './registry-CWjIFWHV.js';
2
+ export { m as matchesScope } from './registry-CWjIFWHV.js';
3
3
 
4
4
  /**
5
5
  * `explainSurface()` — the developer projection.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { J as JsonSchema, c as JsonValue, d as AgentInvocationResult, U as Unsubscribe, a as AgentConsumer, b as AgentSurfaceRegistry } from './registry-XD1QsGQ4.js';
2
- export { e as AGENT_CAPABILITY_ERROR_CODES, f as AgentActionContext, g as AgentActionDefinition, h as AgentActionDescriptor, i as AgentAuthorizationContext, j as AgentCapabilityDescriptorUnion, k as AgentCapabilityErrorCode, l as AgentCapabilityErrorPayload, n as AgentComponentDefinition, o as AgentComponentDescriptor, p as AgentConcurrency, q as AgentEffect, r as AgentEnvironment, s as AgentErrorRetry, t as AgentInvocation, u as AgentInvocationPolicyContext, v as AgentObservationDefinition, w as AgentObservationDescriptor, x as AgentPolicy, y as AgentPolicyContext, z as AgentProcedureBinding, B as AgentProcedureBindingRuntimeConfig, C as AgentProcedureDescriptor, E as AgentProcedureEffect, F as AgentProcedureExecutor, G as AgentProcedureRefDescriptor, H as AgentReadContext, I as AgentRegistrationHandle, A as AgentRouteInfo, K as AgentSchema, L as AgentSchemaError, M as AgentSchemaIssue, N as AgentSurfaceDefinitionError, O as AgentSurfaceDefinitionErrorCode, P as AgentSurfaceError, Q as AgentSurfaceEvent, R as AgentSurfaceLimits, T as AgentSurfaceSnapshot, V as AuditEvent, W as AuditSink, X as CONFIRMATION_ESCALATION, Y as ConfirmationController, Z as ConfirmationEscalation, _ as DEFAULT_LIMITS, D as DiscoveryDecision, $ as InvokeOptions, a0 as PendingConfirmation, a1 as PreconditionFailure, a2 as ProcedureCallInfo, a3 as RegistrationCandidate, a4 as RegistryOptions, S as SnapshotContext, a5 as StandardSchemaV1, a6 as action, a7 as audit, a8 as authenticated, a9 as composeInvokeChain, aa as consoleAuditSink, ab as createAgentSurfaceRegistry, ac as defineAgentComponent, ad as emptyObjectSchema, ae as environment, af as evaluateDiscovery, ag as fromJsonSchema, ah as fromStandardSchema, ai as hasPermission, aj as isAgentSurfaceError, ak as memoryAuditSink, al as observation, am as rateLimit, an as requireConfirmation, ao as tenantBoundary, ap as validateComponentDefinition, aq as validateJsonSchemaDocument, ar as validateValueAgainstSchema } from './registry-XD1QsGQ4.js';
1
+ import { J as JsonSchema, c as JsonValue, d as AgentInvocationResult, U as Unsubscribe, a as AgentConsumer, b as AgentSurfaceRegistry } from './registry-CWjIFWHV.js';
2
+ export { e as AGENT_CAPABILITY_ERROR_CODES, f as AgentActionContext, g as AgentActionContract, h as AgentActionDefinition, i as AgentActionDescriptor, j as AgentAuthorizationContext, k as AgentCapabilityDescriptorUnion, l as AgentCapabilityErrorCode, n as AgentCapabilityErrorPayload, o as AgentComponentContract, p as AgentComponentContractDefinition, q as AgentComponentDefinition, r as AgentComponentDescriptor, s as AgentComponentRuntimeBindings, t as AgentConcurrency, u as AgentEffect, v as AgentEnvironment, w as AgentErrorRetry, x as AgentExposureGateway, y as AgentInvocation, z as AgentInvocationPolicyContext, B as AgentObservationContract, C as AgentObservationDefinition, E as AgentObservationDescriptor, F as AgentPolicy, G as AgentPolicyContext, H as AgentProcedureBinding, I as AgentProcedureBindingRuntimeConfig, K as AgentProcedureContract, L as AgentProcedureContractDefinition, M as AgentProcedureDescriptor, N as AgentProcedureEffect, O as AgentProcedureExecutor, P as AgentProcedureRefDescriptor, Q as AgentReadContext, R as AgentRegistrationHandle, A as AgentRouteInfo, T as AgentSchema, V as AgentSchemaError, W as AgentSchemaIssue, X as AgentSurfaceDefinitionError, Y as AgentSurfaceDefinitionErrorCode, Z as AgentSurfaceError, _ as AgentSurfaceEvent, $ as AgentSurfaceLimits, a0 as AgentSurfaceSnapshot, a1 as AuditEvent, a2 as AuditSink, a3 as CAPABILITY_CONTRACT_FORMAT_VERSION, a4 as COMPILED_CAPABILITY_PROVENANCE, a5 as CONFIRMATION_ESCALATION, a6 as CapabilityContractEntry, a7 as CapabilityContractKind, a8 as CapabilityContractManifest, a9 as CapabilityPolicyAttachment, aa as CompiledCapabilityToken, ab as CompiledComponentProvenance, ac as CompiledExternalAgentTool, ad as ConfirmationController, ae as ConfirmationEscalation, af as DEFAULT_LIMITS, D as DiscoveryDecision, ag as ExternalAgentToolContract, ah as ExternalAgentToolContractDefinition, ai as ExternalCapabilityContractDigest, aj as InvokeOptions, ak as PendingConfirmation, al as PreconditionFailure, am as ProcedureCallInfo, an as RegistrationCandidate, ao as RegistryOptions, S as SnapshotContext, ap as StandardSchemaV1, aq as action, ar as actionContract, as as assertDefinitionInManifest, at as audit, au as authenticated, av as compiledCapabilityToken, aw as composeInvokeChain, ax as consoleAuditSink, ay as createAgentExposureGateway, az as createAgentSurfaceRegistry, aA as defineAgentComponent, aB as defineAgentComponentContract, aC as defineAgentProcedureContract, aD as defineExternalAgentToolContract, aE as emptyObjectSchema, aF as environment, aG as evaluateDiscovery, aH as fromJsonSchema, aI as fromStandardSchema, aJ as hasPermission, aK as isAgentSurfaceError, aL as memoryAuditSink, aM as observation, aN as observationContract, aO as rateLimit, aP as requireConfirmation, aQ as tenantBoundary, aR as tryCompiledCapabilityToken, aS as validateComponentDefinition, aT as validateJsonSchemaDocument, aU as validateValueAgainstSchema } from './registry-CWjIFWHV.js';
3
3
 
4
4
  /**
5
5
  * Canonical ID grammar (docs/01 §identity):
package/dist/index.js CHANGED
@@ -1945,6 +1945,251 @@ function drainObservationQueues(internals) {
1945
1945
  for (const waiter of waiting) waiter.admit(false);
1946
1946
  }
1947
1947
 
1948
+ // src/contract.ts
1949
+ var CAPABILITY_CONTRACT_FORMAT_VERSION = 3;
1950
+ var COMPILED_CAPABILITY_PROVENANCE = /* @__PURE__ */ Symbol.for(
1951
+ "@agent-surface/core.compiled-capability-provenance"
1952
+ );
1953
+ function observationContract(contract) {
1954
+ return contract;
1955
+ }
1956
+ function actionContract(contract) {
1957
+ return contract;
1958
+ }
1959
+ function defineAgentComponentContract(definition, compiled) {
1960
+ const contract = {
1961
+ ...definition,
1962
+ kind: "agent-component-contract",
1963
+ bind(bindings) {
1964
+ const observations = {};
1965
+ for (const [name, authored] of Object.entries(definition.observations ?? {})) {
1966
+ const runtime = bindings.observations?.[name];
1967
+ if (!runtime?.read) {
1968
+ throw new AgentSurfaceDefinitionError(
1969
+ "INVALID_DEFINITION",
1970
+ `contract "${definition.type}" observation "${name}" has no runtime binding`
1971
+ );
1972
+ }
1973
+ observations[name] = {
1974
+ description: authored.description,
1975
+ output: authored.output,
1976
+ read: runtime.read,
1977
+ ...authored.meta ? { meta: authored.meta } : {},
1978
+ ...authored.timeoutMs !== void 0 ? { timeoutMs: authored.timeoutMs } : {},
1979
+ ...runtime.when ? { when: runtime.when } : {},
1980
+ ...runtime.unavailableReason ? { unavailableReason: runtime.unavailableReason } : {},
1981
+ ...runtime.policies ? { policies: runtime.policies } : {}
1982
+ };
1983
+ }
1984
+ const actions = {};
1985
+ for (const [name, authored] of Object.entries(definition.actions ?? {})) {
1986
+ const runtime = bindings.actions?.[name];
1987
+ if (!runtime?.execute) {
1988
+ throw new AgentSurfaceDefinitionError(
1989
+ "INVALID_DEFINITION",
1990
+ `contract "${definition.type}" action "${name}" has no runtime binding`
1991
+ );
1992
+ }
1993
+ actions[name] = {
1994
+ description: authored.description,
1995
+ input: authored.input,
1996
+ ...authored.output ? { output: authored.output } : {},
1997
+ effect: authored.effect,
1998
+ execute: runtime.execute,
1999
+ ...authored.idempotent !== void 0 ? { idempotent: authored.idempotent } : {},
2000
+ ...authored.reversible !== void 0 ? { reversible: authored.reversible } : {},
2001
+ ...authored.confirmation !== void 0 ? { confirmation: authored.confirmation } : {},
2002
+ ...authored.audit !== void 0 ? { audit: authored.audit } : {},
2003
+ ...authored.meta ? { meta: authored.meta } : {},
2004
+ ...authored.timeoutMs !== void 0 ? { timeoutMs: authored.timeoutMs } : {},
2005
+ ...authored.concurrency ? { concurrency: authored.concurrency } : {},
2006
+ ...runtime.when ? { when: runtime.when } : {},
2007
+ ...runtime.unavailableReason ? { unavailableReason: runtime.unavailableReason } : {},
2008
+ ...runtime.precondition ? { precondition: runtime.precondition } : {},
2009
+ ...runtime.policies ? { policies: runtime.policies } : {}
2010
+ };
2011
+ }
2012
+ const bound = {
2013
+ type: definition.type,
2014
+ description: definition.description,
2015
+ ...bindings.instanceId !== void 0 ? { instanceId: bindings.instanceId } : {},
2016
+ ...bindings.parent ? { parent: bindings.parent } : {},
2017
+ ...definition.meta ? { meta: definition.meta } : {},
2018
+ ...bindings.internal ? { internal: bindings.internal } : {},
2019
+ ...bindings.policies ? { policies: bindings.policies } : {},
2020
+ ...definition.origin ? { origin: definition.origin } : {},
2021
+ ...definition.priority !== void 0 ? { priority: definition.priority } : {},
2022
+ ...bindings.enabled !== void 0 ? { enabled: bindings.enabled } : {},
2023
+ ...Object.keys(observations).length > 0 ? { observations } : {},
2024
+ ...Object.keys(actions).length > 0 ? { actions } : {},
2025
+ ...bindings.procedures ? { procedures: bindings.procedures } : {}
2026
+ };
2027
+ if (compiled) {
2028
+ Object.defineProperty(bound, COMPILED_CAPABILITY_PROVENANCE, {
2029
+ value: compiled,
2030
+ enumerable: false
2031
+ });
2032
+ }
2033
+ return bound;
2034
+ }
2035
+ };
2036
+ return contract;
2037
+ }
2038
+ function defineAgentProcedureContract(definition, compiled) {
2039
+ const contract = {
2040
+ kind: "agent-procedure-contract",
2041
+ definition
2042
+ };
2043
+ if (compiled) {
2044
+ Object.defineProperty(contract, COMPILED_CAPABILITY_PROVENANCE, {
2045
+ value: compiled,
2046
+ enumerable: false
2047
+ });
2048
+ }
2049
+ return contract;
2050
+ }
2051
+ function defineExternalAgentToolContract(definition, compiled) {
2052
+ const contract = {
2053
+ kind: "external-agent-tool-contract",
2054
+ definition,
2055
+ bind(binding) {
2056
+ if (!compiled) {
2057
+ throw new AgentSurfaceDefinitionError(
2058
+ "INVALID_DEFINITION",
2059
+ `external contract "${definition.id}" has no compiler provenance`
2060
+ );
2061
+ }
2062
+ const tool = {
2063
+ name: definition.id,
2064
+ description: definition.description,
2065
+ inputSchema: definition.input.jsonSchema,
2066
+ execute: binding.execute
2067
+ };
2068
+ Object.defineProperty(tool, COMPILED_CAPABILITY_PROVENANCE, {
2069
+ value: compiled,
2070
+ enumerable: false
2071
+ });
2072
+ return tool;
2073
+ }
2074
+ };
2075
+ if (compiled) {
2076
+ Object.defineProperty(contract, COMPILED_CAPABILITY_PROVENANCE, {
2077
+ value: compiled,
2078
+ enumerable: false
2079
+ });
2080
+ }
2081
+ return contract;
2082
+ }
2083
+ function compiledCapabilityToken(contract) {
2084
+ const token = contract[COMPILED_CAPABILITY_PROVENANCE];
2085
+ if (!token || "capabilities" in token) {
2086
+ throw new AgentSurfaceDefinitionError(
2087
+ "INVALID_DEFINITION",
2088
+ `contract "${contract.definition.id}" has no compiler provenance`
2089
+ );
2090
+ }
2091
+ return token;
2092
+ }
2093
+ function tryCompiledCapabilityToken(contract) {
2094
+ const token = contract[COMPILED_CAPABILITY_PROVENANCE];
2095
+ return token && !("capabilities" in token) ? token : void 0;
2096
+ }
2097
+ function manifestIndex(manifest) {
2098
+ if (manifest.formatVersion !== CAPABILITY_CONTRACT_FORMAT_VERSION || manifest.completeness?.status !== "proven" || typeof manifest.hash !== "string" || manifest.hash.length === 0) {
2099
+ throw new AgentSurfaceDefinitionError("INVALID_DEFINITION", "invalid compiled capability manifest");
2100
+ }
2101
+ const index = /* @__PURE__ */ new Map();
2102
+ for (const entry of manifest.capabilities) {
2103
+ const key = `${entry.declarationId}\0${entry.capabilityId}`;
2104
+ if (index.has(key)) {
2105
+ throw new AgentSurfaceDefinitionError(
2106
+ "DUPLICATE_CAPABILITY",
2107
+ `duplicate compiled declaration "${entry.declarationId}" for "${entry.capabilityId}"`
2108
+ );
2109
+ }
2110
+ index.set(key, entry);
2111
+ }
2112
+ return index;
2113
+ }
2114
+ function assertToken(token, manifest, index) {
2115
+ if (token.manifestHash !== manifest.hash) {
2116
+ throw new AgentSurfaceDefinitionError(
2117
+ "INVALID_DEFINITION",
2118
+ `stale compiler token for "${token.capabilityId}": manifest hash mismatch`
2119
+ );
2120
+ }
2121
+ const declared = index.get(`${token.declarationId}\0${token.capabilityId}`);
2122
+ if (!declared) {
2123
+ throw new AgentSurfaceDefinitionError(
2124
+ "INVALID_DEFINITION",
2125
+ `unknown compiled declaration "${token.declarationId}" for "${token.capabilityId}"`
2126
+ );
2127
+ }
2128
+ if (declared.contractHash !== token.contractHash) {
2129
+ throw new AgentSurfaceDefinitionError(
2130
+ "INVALID_DEFINITION",
2131
+ `compiled contract hash mismatch for "${token.capabilityId}"`
2132
+ );
2133
+ }
2134
+ }
2135
+ function assertDefinitionInManifest(definition, manifest) {
2136
+ const provenance = definition[COMPILED_CAPABILITY_PROVENANCE];
2137
+ if (!provenance || !("capabilities" in provenance)) {
2138
+ throw new AgentSurfaceDefinitionError(
2139
+ "INVALID_DEFINITION",
2140
+ `raw registration "${definition.type}" rejected: bind a compiler-generated contract`
2141
+ );
2142
+ }
2143
+ if (provenance.manifestHash !== manifest.hash) {
2144
+ throw new AgentSurfaceDefinitionError(
2145
+ "INVALID_DEFINITION",
2146
+ `stale contract "${provenance.declarationId}": manifest hash mismatch`
2147
+ );
2148
+ }
2149
+ const index = manifestIndex(manifest);
2150
+ const expected = [
2151
+ ...Object.keys(definition.observations ?? {}).map((name) => `view:${definition.type}.${name}`),
2152
+ ...Object.keys(definition.actions ?? {}).map((name) => `view:${definition.type}.${name}`),
2153
+ ...(definition.procedures ?? []).map((binding) => binding.ref.id)
2154
+ ];
2155
+ for (const capabilityId of expected) {
2156
+ const token = provenance.capabilities[capabilityId];
2157
+ if (!token) {
2158
+ throw new AgentSurfaceDefinitionError(
2159
+ "INVALID_DEFINITION",
2160
+ `capability "${capabilityId}" is absent from compiled contract "${provenance.declarationId}"`
2161
+ );
2162
+ }
2163
+ assertToken(token, manifest, index);
2164
+ }
2165
+ for (const capabilityId of Object.keys(provenance.capabilities)) {
2166
+ if (!expected.includes(capabilityId)) {
2167
+ throw new AgentSurfaceDefinitionError(
2168
+ "INVALID_DEFINITION",
2169
+ `binding for "${provenance.declarationId}" omits compiled capability "${capabilityId}"`
2170
+ );
2171
+ }
2172
+ }
2173
+ }
2174
+ function createAgentExposureGateway(manifest) {
2175
+ const index = manifestIndex(manifest);
2176
+ return {
2177
+ expose(tools) {
2178
+ return tools.map((tool) => {
2179
+ const token = tool[COMPILED_CAPABILITY_PROVENANCE];
2180
+ if (!token) {
2181
+ throw new AgentSurfaceDefinitionError(
2182
+ "INVALID_DEFINITION",
2183
+ `raw provider tool "${tool.name}" rejected by compiled exposure gateway`
2184
+ );
2185
+ }
2186
+ assertToken(token, manifest, index);
2187
+ return tool;
2188
+ });
2189
+ }
2190
+ };
2191
+ }
2192
+
1948
2193
  // src/registry.ts
1949
2194
  function createAgentSurfaceRegistry(options) {
1950
2195
  const environment2 = options?.environment ?? "production";
@@ -2093,6 +2338,7 @@ function createAgentSurfaceRegistry(options) {
2093
2338
  surfaceId: internals.surfaceId,
2094
2339
  register(definition) {
2095
2340
  if (internals.disposed) throw new Error("register() called on a disposed registry");
2341
+ if (options?.manifest) assertDefinitionInManifest(definition, options.manifest);
2096
2342
  validateComponentDefinition(definition, limits, {
2097
2343
  hasProcedureExecutor: internals.executor !== void 0
2098
2344
  });
@@ -2781,20 +3027,29 @@ export {
2781
3027
  AgentSchemaError,
2782
3028
  AgentSurfaceDefinitionError,
2783
3029
  AgentSurfaceError,
3030
+ CAPABILITY_CONTRACT_FORMAT_VERSION,
3031
+ COMPILED_CAPABILITY_PROVENANCE,
2784
3032
  CONFIRMATION_ESCALATION,
2785
3033
  DEFAULT_LIMITS,
2786
3034
  MAX_ID_LENGTH,
2787
3035
  MAX_WIRE_NAME_LENGTH,
2788
3036
  action,
3037
+ actionContract,
3038
+ assertDefinitionInManifest,
2789
3039
  assignWireNames,
2790
3040
  audit,
2791
3041
  authenticated,
3042
+ compiledCapabilityToken,
2792
3043
  composeInvokeChain,
2793
3044
  consoleAuditSink,
3045
+ createAgentExposureGateway,
2794
3046
  createAgentSurfaceRegistry,
2795
3047
  createAgentToolset,
2796
3048
  decodeWireName,
2797
3049
  defineAgentComponent,
3050
+ defineAgentComponentContract,
3051
+ defineAgentProcedureContract,
3052
+ defineExternalAgentToolContract,
2798
3053
  emptyObjectSchema,
2799
3054
  encodeWireName,
2800
3055
  encodeWireNameForInstance,
@@ -2812,10 +3067,12 @@ export {
2812
3067
  jsonDeepEqual,
2813
3068
  memoryAuditSink,
2814
3069
  observation,
3070
+ observationContract,
2815
3071
  parseCapabilityId,
2816
3072
  rateLimit,
2817
3073
  requireConfirmation,
2818
3074
  tenantBoundary,
3075
+ tryCompiledCapabilityToken,
2819
3076
  validateComponentDefinition,
2820
3077
  validateJsonSchemaDocument,
2821
3078
  validateValueAgainstSchema