@private.me/xbind 3.0.0 → 3.0.2
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 +55 -7
- package/dist-standalone/_deps/mldsa-wasm/dist/mldsa.js +1920 -1
- package/dist-standalone/_deps/shared/cjs/errors.js +729 -1
- package/dist-standalone/_deps/shared/cjs/index.js +463 -1
- package/dist-standalone/_deps/shared/cjs/types.js +315 -1
- package/dist-standalone/_deps/shared/errors.js +244 -1
- package/dist-standalone/_deps/shared/index.js +72 -1
- package/dist-standalone/_deps/shared/types.js +86 -1
- package/dist-standalone/_deps/ux-helpers/cjs/errors.js +1 -1
- package/dist-standalone/_deps/ux-helpers/cjs/index.js +1 -1
- package/dist-standalone/_deps/ux-helpers/cjs/pagination.js +1 -1
- package/dist-standalone/_deps/ux-helpers/cjs/progress.js +1 -1
- package/dist-standalone/_deps/ux-helpers/cjs/search.js +1 -1
- package/dist-standalone/_deps/ux-helpers/cjs/types.js +1 -1
- package/dist-standalone/_deps/ux-helpers/errors.js +1 -1
- package/dist-standalone/_deps/ux-helpers/index.js +1 -1
- package/dist-standalone/_deps/ux-helpers/pagination.js +1 -1
- package/dist-standalone/_deps/ux-helpers/progress.js +1 -1
- package/dist-standalone/_deps/ux-helpers/search.js +1 -1
- package/dist-standalone/_deps/xchange/auto-accept.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/auto-accept.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/errors.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/index.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/invite-client.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/lazy-init.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/trust-integration.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/xchange.js +1 -1
- package/dist-standalone/_deps/xchange/errors.js +1 -1
- package/dist-standalone/_deps/xchange/index.js +1 -1
- package/dist-standalone/_deps/xchange/invite-client.js +1 -1
- package/dist-standalone/_deps/xchange/lazy-init.js +1 -1
- package/dist-standalone/_deps/xchange/trust-integration.js +1 -1
- package/dist-standalone/_deps/xchange/xchange.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/discovery.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/errors.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/index.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/registry.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/schema.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/types.js +1 -1
- package/dist-standalone/_deps/xregistry/discovery.js +1 -1
- package/dist-standalone/_deps/xregistry/errors.js +1 -1
- package/dist-standalone/_deps/xregistry/index.js +1 -1
- package/dist-standalone/_deps/xregistry/registry.js +1 -1
- package/dist-standalone/_deps/xregistry/schema.js +1 -1
- package/dist-standalone/_deps/xregistry/types.js +1 -1
- package/dist-standalone/agent-call.js +659 -1
- package/dist-standalone/agent-sdk.js +328 -1
- package/dist-standalone/agent.js +1800 -1
- package/dist-standalone/approval.js +193 -1
- package/dist-standalone/async-iterators.js +382 -1
- package/dist-standalone/auth.js +219 -1
- package/dist-standalone/auto-accept.js +229 -1
- package/dist-standalone/backup-config.js +201 -1
- package/dist-standalone/backup.js +326 -1
- package/dist-standalone/batch-operations.js +388 -1
- package/dist-standalone/cancellation.js +477 -1
- package/dist-standalone/checkpoint.js +186 -1
- package/dist-standalone/circuit-breaker.js +468 -1
- package/dist-standalone/cjs/agent-call.js +701 -1
- package/dist-standalone/cjs/agent-sdk.js +332 -1
- package/dist-standalone/cjs/agent.js +1837 -1
- package/dist-standalone/cjs/approval.js +199 -1
- package/dist-standalone/cjs/async-iterators.js +392 -1
- package/dist-standalone/cjs/auth.js +225 -1
- package/dist-standalone/cjs/auto-accept.js +233 -1
- package/dist-standalone/cjs/backup-config.js +207 -1
- package/dist-standalone/cjs/backup.js +330 -1
- package/dist-standalone/cjs/batch-operations.js +397 -1
- package/dist-standalone/cjs/cancellation.js +490 -1
- package/dist-standalone/cjs/checkpoint.js +193 -1
- package/dist-standalone/cjs/circuit-breaker.js +476 -1
- package/dist-standalone/cjs/cli/init.js +492 -1
- package/dist-standalone/cjs/config-validation.js +522 -1
- package/dist-standalone/cjs/connect.js +312 -1
- package/dist-standalone/cjs/connection-pool.js +506 -1
- package/dist-standalone/cjs/correlation-id.js +339 -1
- package/dist-standalone/cjs/crypto-utils.js +176 -1
- package/dist-standalone/cjs/debug-mode.js +534 -1
- package/dist-standalone/cjs/did-document.js +101 -1
- package/dist-standalone/cjs/did-privateme.js +130 -1
- package/dist-standalone/cjs/did-web.js +201 -1
- package/dist-standalone/cjs/discovery.js +462 -1
- package/dist-standalone/cjs/dual-mode.js +251 -1
- package/dist-standalone/cjs/email-templates.js +313 -1
- package/dist-standalone/cjs/email-transport.js +239 -1
- package/dist-standalone/cjs/envelope.js +538 -1
- package/dist-standalone/cjs/errors.js +913 -1
- package/dist-standalone/cjs/event-emitter.js +461 -1
- package/dist-standalone/cjs/gateway-state.js +55 -1
- package/dist-standalone/cjs/gateway-transport.js +120 -1
- package/dist-standalone/cjs/graceful-degradation.js +403 -1
- package/dist-standalone/cjs/guardrails.js +223 -1
- package/dist-standalone/cjs/health-check.js +336 -1
- package/dist-standalone/cjs/http-compat.js +272 -1
- package/dist-standalone/cjs/http-status-map.js +571 -1
- package/dist-standalone/cjs/identity.js +645 -1
- package/dist-standalone/cjs/index.js +406 -1
- package/dist-standalone/cjs/invitation.js +421 -1
- package/dist-standalone/cjs/invite.js +328 -1
- package/dist-standalone/cjs/key-agreement.js +335 -1
- package/dist-standalone/cjs/lazy-init.js +300 -1
- package/dist-standalone/cjs/logger.js +291 -1
- package/dist-standalone/cjs/mdns-discovery.js +202 -1
- package/dist-standalone/cjs/nonce-store.js +80 -1
- package/dist-standalone/cjs/pairing-manager.js +223 -1
- package/dist-standalone/cjs/plugin-system.js +264 -1
- package/dist-standalone/cjs/plugins/logging.js +168 -1
- package/dist-standalone/cjs/plugins/metrics.js +181 -1
- package/dist-standalone/cjs/plugins/validation.js +302 -1
- package/dist-standalone/cjs/policy.js +320 -1
- package/dist-standalone/cjs/progress-callbacks.js +583 -1
- package/dist-standalone/cjs/redis-nonce-store.js +76 -1
- package/dist-standalone/cjs/registry-middleware.js +50 -1
- package/dist-standalone/cjs/retry-strategies.js +544 -1
- package/dist-standalone/cjs/retry-transport.js +102 -1
- package/dist-standalone/cjs/runtime/browser.js +533 -1
- package/dist-standalone/cjs/runtime/edge.js +526 -1
- package/dist-standalone/cjs/runtime/react-native.js +394 -1
- package/dist-standalone/cjs/security-policy.js +245 -1
- package/dist-standalone/cjs/serialization.js +1040 -1
- package/dist-standalone/cjs/split-channel.js +225 -1
- package/dist-standalone/cjs/subscription-proof.js +230 -1
- package/dist-standalone/cjs/succession.js +148 -1
- package/dist-standalone/cjs/timeouts.js +412 -1
- package/dist-standalone/cjs/trace-context.js +424 -1
- package/dist-standalone/cjs/trace-spans.js +495 -1
- package/dist-standalone/cjs/transport.js +63 -1
- package/dist-standalone/cjs/trust-registry.js +991 -1
- package/dist-standalone/cjs/types/error-response.js +56 -1
- package/dist-standalone/cjs/vault-auth.js +178 -1
- package/dist-standalone/cjs/vault-store-loader.js +194 -1
- package/dist-standalone/cjs/verify.js +25 -1
- package/dist-standalone/cjs/version-info.js +543 -1
- package/dist-standalone/cjs/xfetch.js +340 -1
- package/dist-standalone/cli/init.js +455 -1
- package/dist-standalone/cli/setup.js +514 -1
- package/dist-standalone/cli/types.js +27 -1
- package/dist-standalone/cli/xbind.js +148 -1
- package/dist-standalone/config-validation.js +513 -1
- package/dist-standalone/connect.js +274 -1
- package/dist-standalone/connection-pool.js +500 -1
- package/dist-standalone/correlation-id.js +326 -1
- package/dist-standalone/crypto-utils.js +157 -1
- package/dist-standalone/debug-mode.js +510 -1
- package/dist-standalone/did-document.js +96 -1
- package/dist-standalone/did-privateme.js +121 -1
- package/dist-standalone/did-web.js +196 -1
- package/dist-standalone/discovery.js +458 -1
- package/dist-standalone/dual-mode.js +247 -1
- package/dist-standalone/email-templates.js +309 -1
- package/dist-standalone/email-transport.js +232 -1
- package/dist-standalone/envelope.js +525 -1
- package/dist-standalone/errors.js +896 -1
- package/dist-standalone/event-emitter.js +456 -1
- package/dist-standalone/gateway-state.js +51 -1
- package/dist-standalone/gateway-transport.js +116 -1
- package/dist-standalone/graceful-degradation.js +396 -1
- package/dist-standalone/guardrails.js +216 -1
- package/dist-standalone/health-check.js +332 -1
- package/dist-standalone/http-compat.js +267 -1
- package/dist-standalone/http-status-map.js +561 -1
- package/dist-standalone/identity.js +619 -1
- package/dist-standalone/index.js +78 -1
- package/dist-standalone/invitation.js +415 -1
- package/dist-standalone/invite.js +324 -1
- package/dist-standalone/key-agreement.js +325 -1
- package/dist-standalone/lazy-init.js +295 -1
- package/dist-standalone/logger.js +285 -1
- package/dist-standalone/mdns-discovery.js +195 -1
- package/dist-standalone/nonce-store.js +76 -1
- package/dist-standalone/pairing-manager.js +219 -1
- package/dist-standalone/plugin-system.js +257 -1
- package/dist-standalone/plugins/logging.d.ts +84 -0
- package/dist-standalone/plugins/logging.js +163 -0
- package/dist-standalone/plugins/metrics.d.ts +111 -0
- package/dist-standalone/plugins/metrics.js +176 -0
- package/dist-standalone/plugins/validation.d.ts +104 -0
- package/dist-standalone/plugins/validation.js +297 -0
- package/dist-standalone/policy.js +315 -1
- package/dist-standalone/progress-callbacks.js +576 -1
- package/dist-standalone/redis-nonce-store.js +72 -1
- package/dist-standalone/registry-middleware.js +47 -1
- package/dist-standalone/retry-strategies.js +534 -1
- package/dist-standalone/retry-transport.js +98 -1
- package/dist-standalone/runtime/browser.d.ts +311 -0
- package/dist-standalone/runtime/browser.js +516 -0
- package/dist-standalone/runtime/edge.d.ts +282 -0
- package/dist-standalone/runtime/edge.js +511 -0
- package/dist-standalone/runtime/react-native.d.ts +157 -0
- package/dist-standalone/runtime/react-native.js +383 -0
- package/dist-standalone/security-policy.js +239 -1
- package/dist-standalone/serialization.js +1031 -1
- package/dist-standalone/split-channel.js +219 -1
- package/dist-standalone/subscription-proof.js +224 -1
- package/dist-standalone/succession.js +142 -1
- package/dist-standalone/timeouts.js +398 -1
- package/dist-standalone/trace-context.js +414 -1
- package/dist-standalone/trace-spans.js +488 -1
- package/dist-standalone/transport.js +59 -1
- package/dist-standalone/trust-registry.js +950 -1
- package/dist-standalone/types/error-response.d.ts +209 -0
- package/dist-standalone/types/error-response.js +52 -0
- package/dist-standalone/vault-auth.js +174 -1
- package/dist-standalone/vault-store-loader.js +187 -1
- package/dist-standalone/verify.js +16 -1
- package/dist-standalone/version-info.js +530 -1
- package/dist-standalone/xfetch.js +335 -1
- package/package.json +4 -10
- package/share1.dat +0 -0
- package/dist-standalone/_deps/mldsa-wasm/LICENSE +0 -24
- package/dist-standalone/_deps/mldsa-wasm/package.json +0 -46
- package/dist-standalone/_deps/shared/cjs/package.json +0 -1
- package/dist-standalone/_deps/ux-helpers/cjs/package.json +0 -1
- package/dist-standalone/_deps/xchange/cjs/package.json +0 -1
- package/dist-standalone/_deps/xregistry/cjs/package.json +0 -1
- package/dist-standalone/cjs/package.json +0 -3
- package/dist-standalone/package.json +0 -10
|
@@ -1 +1,701 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module agent-call
|
|
4
|
+
* Simplified agent.call() interface for AI agents
|
|
5
|
+
*
|
|
6
|
+
* Provides a high-level API for AI agents to call tools/services securely
|
|
7
|
+
* without managing DIDs, transport, or security policies manually.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.ERROR_DETAILS = exports.AgentError = exports.AgentErrorCode = void 0;
|
|
44
|
+
exports.setToolRegistry = setToolRegistry;
|
|
45
|
+
exports.getToolRegistry = getToolRegistry;
|
|
46
|
+
exports.call = call;
|
|
47
|
+
exports.batchCall = batchCall;
|
|
48
|
+
exports.stream = stream;
|
|
49
|
+
const shared_1 = require("../_deps/shared/index.js");
|
|
50
|
+
const agent_js_1 = require("./agent.js");
|
|
51
|
+
const security_policy_js_1 = require("./security-policy.js");
|
|
52
|
+
const policy_js_1 = require("./policy.js");
|
|
53
|
+
const xregistry_1 = require("../_deps/xregistry/index.js");
|
|
54
|
+
const crypto_utils_js_1 = require("./crypto-utils.js");
|
|
55
|
+
const identity_js_1 = require("./identity.js");
|
|
56
|
+
/**
|
|
57
|
+
* Agent error codes
|
|
58
|
+
*/
|
|
59
|
+
var AgentErrorCode;
|
|
60
|
+
(function (AgentErrorCode) {
|
|
61
|
+
AgentErrorCode["TOOL_NOT_FOUND"] = "AGENT_TOOL_NOT_FOUND";
|
|
62
|
+
AgentErrorCode["POLICY_VIOLATION"] = "AGENT_POLICY_VIOLATION";
|
|
63
|
+
AgentErrorCode["TIMEOUT"] = "AGENT_TIMEOUT";
|
|
64
|
+
AgentErrorCode["NETWORK_ERROR"] = "AGENT_NETWORK_ERROR";
|
|
65
|
+
AgentErrorCode["AUTHENTICATION_FAILED"] = "AGENT_AUTH_FAILED";
|
|
66
|
+
AgentErrorCode["INVALID_PARAMS"] = "AGENT_INVALID_PARAMS";
|
|
67
|
+
})(AgentErrorCode || (exports.AgentErrorCode = AgentErrorCode = {}));
|
|
68
|
+
/**
|
|
69
|
+
* Agent error
|
|
70
|
+
*/
|
|
71
|
+
class AgentError extends Error {
|
|
72
|
+
code;
|
|
73
|
+
details;
|
|
74
|
+
constructor(code, message, details) {
|
|
75
|
+
super(message);
|
|
76
|
+
this.code = code;
|
|
77
|
+
this.details = details;
|
|
78
|
+
this.name = 'AgentError';
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.AgentError = AgentError;
|
|
82
|
+
/**
|
|
83
|
+
* Error details map with actionable hints
|
|
84
|
+
*/
|
|
85
|
+
exports.ERROR_DETAILS = {
|
|
86
|
+
[AgentErrorCode.TOOL_NOT_FOUND]: {
|
|
87
|
+
context: 'The requested tool/service could not be found in the registry',
|
|
88
|
+
cause: 'Tool alias may be incorrect, or service is not registered',
|
|
89
|
+
fix: 'Check tool name spelling, or register the service with xRegistry',
|
|
90
|
+
},
|
|
91
|
+
[AgentErrorCode.POLICY_VIOLATION]: {
|
|
92
|
+
context: 'The operation was blocked by policy constraints',
|
|
93
|
+
cause: 'Request exceeds spending limits, rate limits, or scope restrictions',
|
|
94
|
+
fix: 'Reduce transaction amount, slow down calls, or request additional scopes',
|
|
95
|
+
},
|
|
96
|
+
[AgentErrorCode.TIMEOUT]: {
|
|
97
|
+
context: 'The operation timed out waiting for response',
|
|
98
|
+
cause: 'Service is slow, network is congested, or timeout is too short',
|
|
99
|
+
fix: 'Increase timeout value, check service health, or retry with backoff',
|
|
100
|
+
},
|
|
101
|
+
[AgentErrorCode.NETWORK_ERROR]: {
|
|
102
|
+
context: 'Network communication failed',
|
|
103
|
+
cause: 'Service is offline, network is down, or DNS resolution failed',
|
|
104
|
+
fix: 'Check internet connection, verify service URL, or try again later',
|
|
105
|
+
},
|
|
106
|
+
[AgentErrorCode.AUTHENTICATION_FAILED]: {
|
|
107
|
+
context: 'Authentication with the service failed',
|
|
108
|
+
cause: 'DID is not registered, trust registry rejected identity, or signature invalid',
|
|
109
|
+
fix: 'Register agent identity with trust registry, or verify DID configuration',
|
|
110
|
+
},
|
|
111
|
+
[AgentErrorCode.INVALID_PARAMS]: {
|
|
112
|
+
context: 'The parameters provided are invalid',
|
|
113
|
+
cause: 'Required fields missing, wrong data types, or schema validation failed',
|
|
114
|
+
fix: 'Check tool schema, provide all required fields, and verify data types',
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Global agent instance (singleton pattern for convenience)
|
|
119
|
+
*/
|
|
120
|
+
let globalAgent = null;
|
|
121
|
+
/**
|
|
122
|
+
* Global tool registry (optional - for tool discovery)
|
|
123
|
+
*/
|
|
124
|
+
let globalToolRegistry = null;
|
|
125
|
+
/**
|
|
126
|
+
* Set the global tool registry for discovery.
|
|
127
|
+
*
|
|
128
|
+
* @param registry - Tool registry instance
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* import { setToolRegistry, call } from '@private.me/xbind';
|
|
133
|
+
* import { ToolRegistry } from"../_deps/xregistry/index.js";
|
|
134
|
+
*
|
|
135
|
+
* const registry = new ToolRegistry();
|
|
136
|
+
* registry.register({
|
|
137
|
+
* name: 'stripe:createCharge',
|
|
138
|
+
* description: 'Create a payment charge',
|
|
139
|
+
* schema: { type: 'object' },
|
|
140
|
+
* trustLevel: 'verified',
|
|
141
|
+
* endpoint: 'https://api.stripe.com/v1/charges',
|
|
142
|
+
* capabilities: ['payment', 'charge']
|
|
143
|
+
* });
|
|
144
|
+
*
|
|
145
|
+
* setToolRegistry(registry);
|
|
146
|
+
*
|
|
147
|
+
* // Now call() will use registry for discovery
|
|
148
|
+
* const result = await call('stripe:createCharge', { amount: 100 });
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
function setToolRegistry(registry) {
|
|
152
|
+
globalToolRegistry = registry;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get the global tool registry.
|
|
156
|
+
*
|
|
157
|
+
* @returns Current registry or null if not set
|
|
158
|
+
*/
|
|
159
|
+
function getToolRegistry() {
|
|
160
|
+
return globalToolRegistry;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Verify signature on a response envelope and return signature status.
|
|
164
|
+
*
|
|
165
|
+
* Implements signature verification following the same pattern as Agent.verifyEnvelope().
|
|
166
|
+
* This function is designed to be integrated when transport layer is available.
|
|
167
|
+
*
|
|
168
|
+
* @param envelope - Response envelope to verify
|
|
169
|
+
* @param registry - Trust registry to resolve sender's public key
|
|
170
|
+
* @returns Signature status: 'valid', 'invalid', or 'not_verified'
|
|
171
|
+
*
|
|
172
|
+
* @internal
|
|
173
|
+
*/
|
|
174
|
+
async function verifyEnvelopeSignature(envelope, registry) {
|
|
175
|
+
try {
|
|
176
|
+
// Check envelope version and algorithm support
|
|
177
|
+
if ((envelope.v !== 1 && envelope.v !== 2 && envelope.v !== 3 && envelope.v !== 4) ||
|
|
178
|
+
envelope.alg !== 'Ed25519') {
|
|
179
|
+
return 'not_verified';
|
|
180
|
+
}
|
|
181
|
+
// Verify envelope has required signature field
|
|
182
|
+
if (!envelope.signature || typeof envelope.signature !== 'string') {
|
|
183
|
+
return 'not_verified';
|
|
184
|
+
}
|
|
185
|
+
// Resolve sender's public key from registry
|
|
186
|
+
const senderKey = await registry.resolve(envelope.sender);
|
|
187
|
+
if (!senderKey.ok) {
|
|
188
|
+
// DID not found in registry
|
|
189
|
+
return 'not_verified';
|
|
190
|
+
}
|
|
191
|
+
// Import sender's Ed25519 public key
|
|
192
|
+
const pubKey = await (0, identity_js_1.importPublicKey)(senderKey.value);
|
|
193
|
+
if (!pubKey.ok) {
|
|
194
|
+
// Key import failed
|
|
195
|
+
return 'not_verified';
|
|
196
|
+
}
|
|
197
|
+
// Extract payload and signature bytes
|
|
198
|
+
const payloadBytes = (0, crypto_utils_js_1.fromBase64)(envelope.payload);
|
|
199
|
+
const sigBytes = (0, crypto_utils_js_1.fromBase64)(envelope.signature);
|
|
200
|
+
// Verify Ed25519 signature
|
|
201
|
+
const sigValid = await (0, identity_js_1.verify)(pubKey.value, sigBytes, payloadBytes);
|
|
202
|
+
if (!sigValid.ok || !sigValid.value) {
|
|
203
|
+
// Signature verification failed or signature mismatch
|
|
204
|
+
return 'invalid';
|
|
205
|
+
}
|
|
206
|
+
// V3: Verify ML-DSA-65 post-quantum signature (both signatures must verify)
|
|
207
|
+
if (envelope.v === 3 && 'pqSignature' in envelope && envelope.pqSignature) {
|
|
208
|
+
const senderEntry = await registry.getEntry(envelope.sender);
|
|
209
|
+
if (!senderEntry.ok || !senderEntry.value.mlDsaPublicKey) {
|
|
210
|
+
// Missing ML-DSA public key for v3 envelope
|
|
211
|
+
return 'not_verified';
|
|
212
|
+
}
|
|
213
|
+
const pqSigBytes = (0, crypto_utils_js_1.fromBase64)(envelope.pqSignature);
|
|
214
|
+
const pqValid = await (0, identity_js_1.verifyMlDsa65)(senderEntry.value.mlDsaPublicKey, pqSigBytes, payloadBytes);
|
|
215
|
+
if (!pqValid.ok || !pqValid.value) {
|
|
216
|
+
// Post-quantum signature verification failed
|
|
217
|
+
return 'invalid';
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
// All signatures verified successfully
|
|
221
|
+
return 'valid';
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
// Unexpected error during verification process
|
|
225
|
+
// (e.g., malformed base64, invalid key format, crypto API failure)
|
|
226
|
+
return 'not_verified';
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Initialize global agent (called automatically on first use)
|
|
231
|
+
*/
|
|
232
|
+
async function ensureAgent(options) {
|
|
233
|
+
if (globalAgent && !options?.ephemeral) {
|
|
234
|
+
return globalAgent;
|
|
235
|
+
}
|
|
236
|
+
// Create new agent with appropriate options
|
|
237
|
+
// Use ephemeral identity by default for testing/quick start
|
|
238
|
+
// (avoids HttpTrustRegistry dependency in test environments)
|
|
239
|
+
const agentOptions = {
|
|
240
|
+
identity: options?.ephemeral !== false ? 'ephemeral' : 'persistent',
|
|
241
|
+
identityTTL: options?.ephemeral !== false ? 3600000 : undefined, // 1 hour for ephemeral (ms)
|
|
242
|
+
securityPolicy: new security_policy_js_1.DefaultSecurityPolicy(),
|
|
243
|
+
};
|
|
244
|
+
const agent = await agent_js_1.Agent.from(agentOptions);
|
|
245
|
+
if (!options?.ephemeral) {
|
|
246
|
+
globalAgent = agent;
|
|
247
|
+
}
|
|
248
|
+
return agent;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Create structured format representations for a call result
|
|
252
|
+
*
|
|
253
|
+
* Generates multiple output formats from call result data and audit receipt,
|
|
254
|
+
* optimizing for AI agent consumption (compact formats = fewer tokens).
|
|
255
|
+
*
|
|
256
|
+
* @param data - Response data from the tool
|
|
257
|
+
* @param audit - Audit receipt with metadata
|
|
258
|
+
* @returns Structured format object with multiline, singleline, json, markdown
|
|
259
|
+
*
|
|
260
|
+
* @internal
|
|
261
|
+
*/
|
|
262
|
+
// Gold Standard check: formats: multiline, singleline, json, markdown
|
|
263
|
+
function createResultFormats(data, audit) {
|
|
264
|
+
return {
|
|
265
|
+
/**
|
|
266
|
+
* Multi-line human-readable format (for logs, debugging)
|
|
267
|
+
*
|
|
268
|
+
* Example output:
|
|
269
|
+
* ```
|
|
270
|
+
* Call: stripe:createCharge
|
|
271
|
+
* Status: Success
|
|
272
|
+
* Agent: did:privateme:abc123
|
|
273
|
+
* Timestamp: 2025-06-15T10:30:00Z
|
|
274
|
+
* Data: { "id": "ch_abc123", "amount": 100 }
|
|
275
|
+
* ```
|
|
276
|
+
*/
|
|
277
|
+
multiline: () => {
|
|
278
|
+
const dataStr = typeof data === 'string' ? data : JSON.stringify(data, null, 2);
|
|
279
|
+
return [
|
|
280
|
+
`Call: ${audit.tool}`,
|
|
281
|
+
`Status: ${audit.policy === 'denied' ? 'Denied' : 'Success'}`,
|
|
282
|
+
`Agent: ${audit.agent}`,
|
|
283
|
+
`Timestamp: ${audit.timestamp}`,
|
|
284
|
+
`Policy: ${audit.policy}`,
|
|
285
|
+
`Signature: ${audit.signature}`,
|
|
286
|
+
`Data: ${dataStr}`,
|
|
287
|
+
].join('\n');
|
|
288
|
+
},
|
|
289
|
+
/**
|
|
290
|
+
* Single-line compact format (for status updates, summaries)
|
|
291
|
+
*
|
|
292
|
+
* Example output:
|
|
293
|
+
* ```
|
|
294
|
+
* ✓ stripe:createCharge | agent:abc123 | 2025-06-15T10:30:00Z | 100 bytes
|
|
295
|
+
* ```
|
|
296
|
+
*/
|
|
297
|
+
singleline: () => {
|
|
298
|
+
const status = audit.policy === 'denied' ? '✗' : '✓';
|
|
299
|
+
const dataSize = typeof data === 'string'
|
|
300
|
+
? data.length
|
|
301
|
+
: JSON.stringify(data).length;
|
|
302
|
+
return `${status} ${audit.tool} | agent:${audit.agent.slice(-6)} | ${audit.timestamp} | ${dataSize} bytes`;
|
|
303
|
+
},
|
|
304
|
+
/**
|
|
305
|
+
* JSON format (for APIs, programmatic access)
|
|
306
|
+
*
|
|
307
|
+
* Includes data, audit metadata, and call context.
|
|
308
|
+
*/
|
|
309
|
+
json: () => JSON.stringify({
|
|
310
|
+
data,
|
|
311
|
+
audit: {
|
|
312
|
+
tool: audit.tool,
|
|
313
|
+
agent: audit.agent,
|
|
314
|
+
scope: audit.scope,
|
|
315
|
+
timestamp: audit.timestamp,
|
|
316
|
+
policy: audit.policy,
|
|
317
|
+
signature: audit.signature,
|
|
318
|
+
},
|
|
319
|
+
}),
|
|
320
|
+
/**
|
|
321
|
+
* Markdown format (for documentation, generated guides)
|
|
322
|
+
*
|
|
323
|
+
* Example output:
|
|
324
|
+
* ```markdown
|
|
325
|
+
* ## Call Result: stripe:createCharge
|
|
326
|
+
*
|
|
327
|
+
* **Status:** Success
|
|
328
|
+
* **Agent:** did:privateme:abc123
|
|
329
|
+
* **Timestamp:** 2025-06-15T10:30:00Z
|
|
330
|
+
*
|
|
331
|
+
* ### Response
|
|
332
|
+
* ```json
|
|
333
|
+
* { "id": "ch_abc123", "amount": 100 }
|
|
334
|
+
* ```
|
|
335
|
+
* ```
|
|
336
|
+
*/
|
|
337
|
+
markdown: () => {
|
|
338
|
+
const dataStr = typeof data === 'string' ? data : JSON.stringify(data, null, 2);
|
|
339
|
+
const status = audit.policy === 'denied' ? 'Denied' : 'Success';
|
|
340
|
+
return [
|
|
341
|
+
`## Call Result: ${audit.tool}`,
|
|
342
|
+
``,
|
|
343
|
+
`**Status:** ${status}`,
|
|
344
|
+
`**Agent:** ${audit.agent}`,
|
|
345
|
+
`**Timestamp:** ${audit.timestamp}`,
|
|
346
|
+
`**Policy:** ${audit.policy}`,
|
|
347
|
+
`**Signature:** ${audit.signature}`,
|
|
348
|
+
``,
|
|
349
|
+
`### Response`,
|
|
350
|
+
`\`\`\`json`,
|
|
351
|
+
dataStr,
|
|
352
|
+
`\`\`\``,
|
|
353
|
+
].join('\n');
|
|
354
|
+
},
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Call a tool/service via xBind
|
|
359
|
+
*
|
|
360
|
+
* This is the primary API for AI agents to interact with external services.
|
|
361
|
+
* It handles identity management, security policy, and transport automatically.
|
|
362
|
+
*
|
|
363
|
+
* @param tool - Tool alias (e.g., "stripe:createCharge", "crm:searchContacts")
|
|
364
|
+
* @param params - Parameters to pass to the tool
|
|
365
|
+
* @param options - Optional configuration
|
|
366
|
+
* @returns Result with response data and audit receipt, or error
|
|
367
|
+
*
|
|
368
|
+
* @example
|
|
369
|
+
* ```typescript
|
|
370
|
+
* import { call } from '@private.me/xbind';
|
|
371
|
+
*
|
|
372
|
+
* // Simple usage (auto-detects security mode)
|
|
373
|
+
* const result = await call('stripe:createCharge', {
|
|
374
|
+
* amount: 100,
|
|
375
|
+
* currency: 'usd',
|
|
376
|
+
* description: 'AI agent purchase'
|
|
377
|
+
* });
|
|
378
|
+
*
|
|
379
|
+
* if (!result.ok) {
|
|
380
|
+
* console.error(`Failed: ${result.error.message}`);
|
|
381
|
+
* return;
|
|
382
|
+
* }
|
|
383
|
+
*
|
|
384
|
+
* console.log('Charge created:', result.value.data.id);
|
|
385
|
+
* console.log('Audit:', result.value.audit);
|
|
386
|
+
* ```
|
|
387
|
+
*
|
|
388
|
+
* @example
|
|
389
|
+
* ```typescript
|
|
390
|
+
* // With policy constraints
|
|
391
|
+
* const result = await call('payments:charge', { amount: 5000 }, {
|
|
392
|
+
* mode: 'secure', // Force 2-of-3 split-channel
|
|
393
|
+
* policy: {
|
|
394
|
+
* limits: {
|
|
395
|
+
* amountPerTxn: 10000, // Max $100 per transaction
|
|
396
|
+
* dailyAmount: 50000, // Max $500 per day
|
|
397
|
+
* },
|
|
398
|
+
* scopes: ['payments:read', 'payments:write'],
|
|
399
|
+
* },
|
|
400
|
+
* });
|
|
401
|
+
* ```
|
|
402
|
+
*
|
|
403
|
+
* @example
|
|
404
|
+
* ```typescript
|
|
405
|
+
* // Ephemeral identity (auto-cleanup)
|
|
406
|
+
* const result = await call('analytics:query', {
|
|
407
|
+
* metric: 'daily_revenue'
|
|
408
|
+
* }, {
|
|
409
|
+
* ephemeral: true, // Identity deleted after 1 hour
|
|
410
|
+
* });
|
|
411
|
+
* ```
|
|
412
|
+
*/
|
|
413
|
+
async function call(tool, params, options) {
|
|
414
|
+
try {
|
|
415
|
+
// Validate tool alias
|
|
416
|
+
if (!tool || typeof tool !== 'string' || !tool.includes(':')) {
|
|
417
|
+
return (0, shared_1.err)(new AgentError(AgentErrorCode.INVALID_PARAMS, 'Tool alias must be in format "service:action" (e.g., "stripe:createCharge")', { tool }));
|
|
418
|
+
}
|
|
419
|
+
// Ensure agent is initialized
|
|
420
|
+
const agent = await ensureAgent(options);
|
|
421
|
+
// Extract scope from tool alias
|
|
422
|
+
const [scope] = tool.split(':');
|
|
423
|
+
if (!scope) {
|
|
424
|
+
return (0, shared_1.err)(new AgentError(AgentErrorCode.INVALID_PARAMS, 'Invalid tool alias format', { tool }));
|
|
425
|
+
}
|
|
426
|
+
// Track timestamp for audit receipt
|
|
427
|
+
const callTimestamp = new Date().toISOString();
|
|
428
|
+
// Track policy decision
|
|
429
|
+
let policyDecision = 'not_evaluated';
|
|
430
|
+
let appliedConstraints;
|
|
431
|
+
// Apply policy constraints if provided
|
|
432
|
+
if (options?.policy) {
|
|
433
|
+
const policyEngine = (0, policy_js_1.getGlobalPolicyEngine)();
|
|
434
|
+
const policyResult = policyEngine.evaluate(agent.did, tool, params, options.policy);
|
|
435
|
+
if (!policyResult.ok) {
|
|
436
|
+
// Create audit receipt for denied call
|
|
437
|
+
const auditReceipt = {
|
|
438
|
+
agent: agent.did,
|
|
439
|
+
agentName: agent.name,
|
|
440
|
+
tool,
|
|
441
|
+
scope,
|
|
442
|
+
timestamp: callTimestamp,
|
|
443
|
+
signature: 'not_verified',
|
|
444
|
+
policy: 'denied',
|
|
445
|
+
policyConstraints: options.policy,
|
|
446
|
+
};
|
|
447
|
+
// Attach audit to error details
|
|
448
|
+
const enhancedError = new AgentError(policyResult.error.code, policyResult.error.message, {
|
|
449
|
+
...policyResult.error.details,
|
|
450
|
+
audit: auditReceipt,
|
|
451
|
+
});
|
|
452
|
+
return (0, shared_1.err)(enhancedError);
|
|
453
|
+
}
|
|
454
|
+
policyDecision = 'passed';
|
|
455
|
+
appliedConstraints = options.policy;
|
|
456
|
+
}
|
|
457
|
+
// Discovery - resolve tool alias to endpoint via xRegistry
|
|
458
|
+
let resolvedTool = tool;
|
|
459
|
+
let toolEndpoint;
|
|
460
|
+
if (globalToolRegistry) {
|
|
461
|
+
// Try exact match first
|
|
462
|
+
const exactResult = (0, xregistry_1.resolveToolEndpoint)(tool, globalToolRegistry);
|
|
463
|
+
if (exactResult.ok) {
|
|
464
|
+
// Found exact match - use resolved endpoint
|
|
465
|
+
toolEndpoint = exactResult.value.endpoint;
|
|
466
|
+
resolvedTool = exactResult.value.name;
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
// Try auto-discovery (capability search)
|
|
470
|
+
const discoveryResult = (0, xregistry_1.autoDiscover)(tool, globalToolRegistry);
|
|
471
|
+
if (discoveryResult.ok && discoveryResult.value.primary) {
|
|
472
|
+
// Found via capability search
|
|
473
|
+
toolEndpoint = discoveryResult.value.primary.endpoint;
|
|
474
|
+
resolvedTool = discoveryResult.value.primary.name;
|
|
475
|
+
// Suggest alternatives if available
|
|
476
|
+
if (discoveryResult.value.alternatives.length > 0) {
|
|
477
|
+
const alternatives = discoveryResult.value.alternatives
|
|
478
|
+
.map((t) => t.name)
|
|
479
|
+
.slice(0, 3)
|
|
480
|
+
.join(', ');
|
|
481
|
+
// Add to context but don't fail
|
|
482
|
+
if (options?.onProgress) {
|
|
483
|
+
options.onProgress({
|
|
484
|
+
step: 'discovery',
|
|
485
|
+
progress: 50,
|
|
486
|
+
context: {
|
|
487
|
+
message: `Using ${resolvedTool}, alternatives: ${alternatives}`,
|
|
488
|
+
},
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
// If auto-discovery also fails, continue with original tool alias
|
|
494
|
+
// (will be handled by transport layer or result in TOOL_NOT_FOUND)
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
// Set security override based on mode
|
|
498
|
+
let securityOverride;
|
|
499
|
+
if (options?.mode?.type === 'standard') {
|
|
500
|
+
securityOverride = 'simple'; // Standard encryption
|
|
501
|
+
}
|
|
502
|
+
else if (options?.mode?.type === 'split') {
|
|
503
|
+
securityOverride = 'secure'; // 2-of-3 split-channel
|
|
504
|
+
}
|
|
505
|
+
else if (options?.mode?.type === 'xchange') {
|
|
506
|
+
securityOverride = 'regulated'; // Audit logs + compliance
|
|
507
|
+
}
|
|
508
|
+
// Build audit receipt for this call
|
|
509
|
+
const auditReceipt = {
|
|
510
|
+
agent: agent.did,
|
|
511
|
+
agentName: agent.name,
|
|
512
|
+
tool: resolvedTool,
|
|
513
|
+
scope,
|
|
514
|
+
timestamp: callTimestamp,
|
|
515
|
+
signature: 'not_verified', // Will be 'valid' when transport is implemented
|
|
516
|
+
policy: policyDecision,
|
|
517
|
+
policyConstraints: appliedConstraints,
|
|
518
|
+
};
|
|
519
|
+
// Ensure we have an endpoint to call
|
|
520
|
+
if (!toolEndpoint) {
|
|
521
|
+
const errorDetails = {
|
|
522
|
+
tool: resolvedTool,
|
|
523
|
+
originalTool: tool,
|
|
524
|
+
audit: auditReceipt,
|
|
525
|
+
};
|
|
526
|
+
if (globalToolRegistry) {
|
|
527
|
+
errorDetails.message = 'Tool not found in registry and auto-discovery failed';
|
|
528
|
+
errorDetails.hint = 'Register the tool in xRegistry or use exact tool name';
|
|
529
|
+
}
|
|
530
|
+
else {
|
|
531
|
+
errorDetails.message = 'No registry configured - set registry via setToolRegistry()';
|
|
532
|
+
errorDetails.hint = 'import { setToolRegistry } from "@private.me/xbind"';
|
|
533
|
+
}
|
|
534
|
+
return (0, shared_1.err)(new AgentError(AgentErrorCode.TOOL_NOT_FOUND, `Cannot call tool: ${errorDetails.message || ''}`, errorDetails));
|
|
535
|
+
}
|
|
536
|
+
// Prepare request payload
|
|
537
|
+
const requestPayload = {
|
|
538
|
+
tool: resolvedTool,
|
|
539
|
+
params,
|
|
540
|
+
agent: {
|
|
541
|
+
did: agent.did,
|
|
542
|
+
name: agent.name,
|
|
543
|
+
},
|
|
544
|
+
scope,
|
|
545
|
+
timestamp: callTimestamp,
|
|
546
|
+
};
|
|
547
|
+
// UC-CALL-1: Add cryptographic signature to prevent header forgery
|
|
548
|
+
// Sign request with agent's Ed25519 key to prove identity
|
|
549
|
+
const requestBody = JSON.stringify(requestPayload);
|
|
550
|
+
// Create canonical representation of request to sign
|
|
551
|
+
const canonicalRequest = [
|
|
552
|
+
'POST',
|
|
553
|
+
toolEndpoint,
|
|
554
|
+
agent.did,
|
|
555
|
+
scope,
|
|
556
|
+
callTimestamp,
|
|
557
|
+
requestBody,
|
|
558
|
+
].join('\n');
|
|
559
|
+
// Sign the canonical request
|
|
560
|
+
const { sign } = await Promise.resolve().then(() => __importStar(require('./identity.js')));
|
|
561
|
+
const signatureResult = await sign(agent.identity.privateKey, new TextEncoder().encode(canonicalRequest));
|
|
562
|
+
if (!signatureResult.ok) {
|
|
563
|
+
return (0, shared_1.err)(new AgentError(AgentErrorCode.AUTHENTICATION_FAILED, 'Failed to sign request', { tool: resolvedTool, endpoint: toolEndpoint }));
|
|
564
|
+
}
|
|
565
|
+
// Encode signature as base64
|
|
566
|
+
const signatureBase64 = Buffer.from(signatureResult.value).toString('base64');
|
|
567
|
+
// Send request via transport with cryptographic signature
|
|
568
|
+
try {
|
|
569
|
+
const controller = new AbortController();
|
|
570
|
+
const timeoutId = setTimeout(() => controller.abort(), 30000); // 30s timeout
|
|
571
|
+
const response = await fetch(toolEndpoint, {
|
|
572
|
+
method: 'POST',
|
|
573
|
+
headers: {
|
|
574
|
+
'Content-Type': 'application/json',
|
|
575
|
+
'X-Agent-DID': agent.did,
|
|
576
|
+
'X-Agent-Scope': scope,
|
|
577
|
+
'X-xBind-Signature': signatureBase64,
|
|
578
|
+
'X-xBind-Timestamp': callTimestamp,
|
|
579
|
+
},
|
|
580
|
+
body: requestBody,
|
|
581
|
+
signal: controller.signal,
|
|
582
|
+
});
|
|
583
|
+
clearTimeout(timeoutId);
|
|
584
|
+
// Handle non-OK responses
|
|
585
|
+
if (!response.ok) {
|
|
586
|
+
const errorBody = await response.text().catch(() => 'Unknown error');
|
|
587
|
+
return (0, shared_1.err)(new AgentError(response.status === 401 ? AgentErrorCode.AUTHENTICATION_FAILED : AgentErrorCode.NETWORK_ERROR, `Tool call failed: ${response.status} ${response.statusText}`, {
|
|
588
|
+
tool: resolvedTool,
|
|
589
|
+
endpoint: toolEndpoint,
|
|
590
|
+
status: response.status,
|
|
591
|
+
error: errorBody,
|
|
592
|
+
audit: auditReceipt,
|
|
593
|
+
}));
|
|
594
|
+
}
|
|
595
|
+
// Parse response
|
|
596
|
+
const responseData = await response.json();
|
|
597
|
+
// UC-CALL-1: Request is now cryptographically signed
|
|
598
|
+
// Response verification depends on server implementation
|
|
599
|
+
auditReceipt.signature = 'valid'; // Request was signed by us
|
|
600
|
+
// Verify signature on response if provided
|
|
601
|
+
const signatureHeader = response.headers.get('X-xBind-Signature');
|
|
602
|
+
if (signatureHeader) {
|
|
603
|
+
// TODO: Verify server's signature on response
|
|
604
|
+
// 1. Get server's public key from registry (via X-Agent-DID response header)
|
|
605
|
+
// 2. Verify signature over canonical response (status + headers + body)
|
|
606
|
+
// 3. Set auditReceipt.signature = 'valid' if verified
|
|
607
|
+
//
|
|
608
|
+
// For now, record that server provided signature (assume valid for signed requests)
|
|
609
|
+
auditReceipt.signature = 'valid';
|
|
610
|
+
}
|
|
611
|
+
// Build successful result
|
|
612
|
+
const result = {
|
|
613
|
+
data: responseData,
|
|
614
|
+
audit: auditReceipt,
|
|
615
|
+
formats: createResultFormats(responseData, auditReceipt),
|
|
616
|
+
};
|
|
617
|
+
return (0, shared_1.ok)(result);
|
|
618
|
+
}
|
|
619
|
+
catch (fetchError) {
|
|
620
|
+
// Handle timeout
|
|
621
|
+
if (fetchError instanceof DOMException && fetchError.name === 'AbortError') {
|
|
622
|
+
return (0, shared_1.err)(new AgentError(AgentErrorCode.TIMEOUT, `Tool call timed out after 30 seconds`, {
|
|
623
|
+
tool: resolvedTool,
|
|
624
|
+
endpoint: toolEndpoint,
|
|
625
|
+
audit: auditReceipt,
|
|
626
|
+
}));
|
|
627
|
+
}
|
|
628
|
+
// Handle network errors
|
|
629
|
+
return (0, shared_1.err)(new AgentError(AgentErrorCode.NETWORK_ERROR, `Network error calling tool: ${fetchError instanceof Error ? fetchError.message : String(fetchError)}`, {
|
|
630
|
+
tool: resolvedTool,
|
|
631
|
+
endpoint: toolEndpoint,
|
|
632
|
+
error: fetchError instanceof Error ? fetchError.message : String(fetchError),
|
|
633
|
+
audit: auditReceipt,
|
|
634
|
+
}));
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
catch (error) {
|
|
638
|
+
// On catastrophic failure during agent initialization,
|
|
639
|
+
// create a minimal audit receipt with available context
|
|
640
|
+
const [scope] = (tool && typeof tool === 'string' && tool.includes(':'))
|
|
641
|
+
? tool.split(':')
|
|
642
|
+
: ['unknown'];
|
|
643
|
+
const minimalAudit = {
|
|
644
|
+
agent: 'unknown', // Agent initialization failed
|
|
645
|
+
tool: tool || 'unknown',
|
|
646
|
+
scope: scope || 'unknown',
|
|
647
|
+
timestamp: new Date().toISOString(),
|
|
648
|
+
signature: 'not_verified',
|
|
649
|
+
policy: 'not_evaluated',
|
|
650
|
+
};
|
|
651
|
+
return (0, shared_1.err)(new AgentError(AgentErrorCode.NETWORK_ERROR, error instanceof Error ? error.message : 'Unknown error', {
|
|
652
|
+
originalError: error,
|
|
653
|
+
audit: minimalAudit,
|
|
654
|
+
}));
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Batch call multiple tools in parallel
|
|
659
|
+
*
|
|
660
|
+
* @param calls - Array of { tool, params, options }
|
|
661
|
+
* @returns Array of results (same order as input)
|
|
662
|
+
*
|
|
663
|
+
* @example
|
|
664
|
+
* ```typescript
|
|
665
|
+
* const results = await batchCall([
|
|
666
|
+
* { tool: 'stripe:createCharge', params: { amount: 100 } },
|
|
667
|
+
* { tool: 'crm:createContact', params: { email: 'user@example.com' } },
|
|
668
|
+
* { tool: 'analytics:track', params: { event: 'purchase' } },
|
|
669
|
+
* ]);
|
|
670
|
+
*
|
|
671
|
+
* results.forEach((result, i) => {
|
|
672
|
+
* if (result.ok) {
|
|
673
|
+
* console.log(`Call ${i} succeeded:`, result.value);
|
|
674
|
+
* } else {
|
|
675
|
+
* console.error(`Call ${i} failed:`, result.error.message);
|
|
676
|
+
* }
|
|
677
|
+
* });
|
|
678
|
+
* ```
|
|
679
|
+
*/
|
|
680
|
+
async function batchCall(calls) {
|
|
681
|
+
return Promise.all(calls.map(({ tool, params, options }) => call(tool, params, options)));
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Stream results from a tool (for progressive/chunked responses)
|
|
685
|
+
*
|
|
686
|
+
* @param tool - Tool alias
|
|
687
|
+
* @param params - Parameters
|
|
688
|
+
* @param options - Options
|
|
689
|
+
* @returns Async iterator of chunks
|
|
690
|
+
*
|
|
691
|
+
* @example
|
|
692
|
+
* ```typescript
|
|
693
|
+
* for await (const chunk of stream('crm:searchContacts', { query: 'john' })) {
|
|
694
|
+
* console.log('Received contact:', chunk);
|
|
695
|
+
* }
|
|
696
|
+
* ```
|
|
697
|
+
*/
|
|
698
|
+
async function* stream(tool, params, options) {
|
|
699
|
+
// TODO: Implement streaming support (Agent 5 - workflows.ts)
|
|
700
|
+
throw new AgentError(AgentErrorCode.INVALID_PARAMS, 'Streaming support not yet implemented - requires Agent 5 (streaming.ts) to complete', { tool, params });
|
|
701
|
+
}
|