@agent-assembly/sdk 0.0.1-beta.2 → 0.0.1-beta.4
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/dist/cjs/core/gateway-resolver.js +124 -9
- package/dist/cjs/core/init-assembly.js +165 -34
- package/dist/cjs/gateway/client.js +64 -1
- package/dist/cjs/gateway/index.js +2 -1
- package/dist/cjs/hooks/ai-sdk.js +3 -5
- package/dist/cjs/hooks/langchain.js +12 -3
- package/dist/cjs/hooks/mastra.js +10 -6
- package/dist/cjs/hooks/openai-agents.js +1 -3
- package/dist/cjs/native/client.js +70 -25
- package/dist/cjs/op-control.js +55 -1
- package/dist/cjs/runtime.js +73 -7
- package/dist/esm/core/gateway-resolver.js +123 -9
- package/dist/esm/core/gateway-resolver.js.map +1 -1
- package/dist/esm/core/init-assembly.js +163 -33
- package/dist/esm/core/init-assembly.js.map +1 -1
- package/dist/esm/gateway/client.js +63 -1
- package/dist/esm/gateway/client.js.map +1 -1
- package/dist/esm/gateway/index.js +1 -1
- package/dist/esm/gateway/index.js.map +1 -1
- package/dist/esm/hooks/ai-sdk.js +3 -5
- package/dist/esm/hooks/ai-sdk.js.map +1 -1
- package/dist/esm/hooks/langchain.js +12 -3
- package/dist/esm/hooks/langchain.js.map +1 -1
- package/dist/esm/hooks/mastra.js +10 -6
- package/dist/esm/hooks/mastra.js.map +1 -1
- package/dist/esm/hooks/openai-agents.js +1 -3
- package/dist/esm/hooks/openai-agents.js.map +1 -1
- package/dist/esm/native/client.js +68 -24
- package/dist/esm/native/client.js.map +1 -1
- package/dist/esm/op-control.js +53 -1
- package/dist/esm/op-control.js.map +1 -1
- package/dist/esm/runtime.js +72 -7
- package/dist/esm/runtime.js.map +1 -1
- package/dist/types/core/gateway-resolver.d.ts +33 -4
- package/dist/types/core/gateway-resolver.d.ts.map +1 -1
- package/dist/types/core/init-assembly.d.ts +6 -1
- package/dist/types/core/init-assembly.d.ts.map +1 -1
- package/dist/types/gateway/client.d.ts +24 -1
- package/dist/types/gateway/client.d.ts.map +1 -1
- package/dist/types/gateway/index.d.ts +1 -1
- package/dist/types/gateway/index.d.ts.map +1 -1
- package/dist/types/hooks/ai-sdk.d.ts.map +1 -1
- package/dist/types/hooks/langchain.d.ts +11 -0
- package/dist/types/hooks/langchain.d.ts.map +1 -1
- package/dist/types/hooks/mastra.d.ts.map +1 -1
- package/dist/types/hooks/openai-agents.d.ts.map +1 -1
- package/dist/types/native/client.d.ts +33 -0
- package/dist/types/native/client.d.ts.map +1 -1
- package/dist/types/op-control.d.ts +29 -2
- package/dist/types/op-control.d.ts.map +1 -1
- package/dist/types/runtime.d.ts +27 -5
- package/dist/types/runtime.d.ts.map +1 -1
- package/dist/types/types/assembly-config.d.ts +14 -0
- package/dist/types/types/assembly-config.d.ts.map +1 -1
- package/native/aa-ffi-node/index.d.ts +74 -0
- package/package.json +7 -7
|
@@ -33,7 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.__testing = exports.AASM_AUTO_START_ARGV = exports.ENV_API_KEY = exports.ENV_GATEWAY_URL = exports.DEFAULT_CONFIG_FILE_PATH = exports.DEFAULT_AUTO_START_TIMEOUT_MS = exports.DEFAULT_PROBE_TIMEOUT_MS = exports.DEFAULT_HEALTHZ_PATH = exports.DEFAULT_GATEWAY_URL = void 0;
|
|
36
|
+
exports.__testing = exports.AASM_AUTO_START_ARGV = exports.LEGACY_ENV_API_KEY = exports.LEGACY_ENV_GATEWAY_URL = exports.ENV_AUTO_START = exports.ENV_API_KEY = exports.ENV_GATEWAY_URL = exports.DEFAULT_CONFIG_FILE_PATH = exports.DEFAULT_AUTO_START_TIMEOUT_MS = exports.DEFAULT_PROBE_TIMEOUT_MS = exports.DEFAULT_HEALTHZ_PATH = exports.DEFAULT_GATEWAY_URL = void 0;
|
|
37
|
+
exports.assertAllowedAasmPath = assertAllowedAasmPath;
|
|
37
38
|
exports.probeHealthz = probeHealthz;
|
|
38
39
|
exports.waitForHealthz = waitForHealthz;
|
|
39
40
|
exports.loadConfigFile = loadConfigFile;
|
|
@@ -56,17 +57,109 @@ const index_js_1 = require("../errors/index.js");
|
|
|
56
57
|
* Resolution precedence (highest first):
|
|
57
58
|
*
|
|
58
59
|
* 1. Explicit field on the AssemblyConfig
|
|
59
|
-
* 2. Environment variable
|
|
60
|
+
* 2. Environment variable — canonical ``AA_GATEWAY_URL`` / ``AA_API_KEY``,
|
|
61
|
+
* with the legacy ``AAASM_GATEWAY_URL`` / ``AAASM_API_KEY`` names accepted
|
|
62
|
+
* as deprecated aliases (a one-time warning is logged when a legacy name
|
|
63
|
+
* supplies the value)
|
|
60
64
|
* 3. Config file (~/.aasm/config.yaml, optional js-yaml soft dep)
|
|
61
|
-
* 4. Local default: probe http://localhost:7391, auto-start
|
|
65
|
+
* 4. Local default: probe http://localhost:7391; when absent, auto-start the
|
|
66
|
+
* local `aasm` gateway ONLY if `AA_AUTO_START` is opted in and the binary
|
|
67
|
+
* resolves to an allow-listed install dir — otherwise raise an error.
|
|
62
68
|
*/
|
|
63
69
|
exports.DEFAULT_GATEWAY_URL = "http://localhost:7391";
|
|
64
70
|
exports.DEFAULT_HEALTHZ_PATH = "/healthz";
|
|
65
71
|
exports.DEFAULT_PROBE_TIMEOUT_MS = 500;
|
|
66
72
|
exports.DEFAULT_AUTO_START_TIMEOUT_MS = 5000;
|
|
67
73
|
exports.DEFAULT_CONFIG_FILE_PATH = "~/.aasm/config.yaml";
|
|
68
|
-
exports.ENV_GATEWAY_URL = "
|
|
69
|
-
exports.ENV_API_KEY = "
|
|
74
|
+
exports.ENV_GATEWAY_URL = "AA_GATEWAY_URL";
|
|
75
|
+
exports.ENV_API_KEY = "AA_API_KEY";
|
|
76
|
+
/**
|
|
77
|
+
* Opt-in gate for auto-starting a local gateway. Auto-start spawns the `aasm`
|
|
78
|
+
* binary resolved from `$PATH`, so it is gated behind an explicit opt-in rather
|
|
79
|
+
* than running silently: a `$PATH` entry an attacker can write to would
|
|
80
|
+
* otherwise be executed by any process that calls `initAssembly()`. Set to
|
|
81
|
+
* `1`/`true`/`yes` to permit auto-start.
|
|
82
|
+
*/
|
|
83
|
+
exports.ENV_AUTO_START = "AA_AUTO_START";
|
|
84
|
+
/** Truthy values that enable {@link ENV_AUTO_START}. */
|
|
85
|
+
function autoStartEnabled() {
|
|
86
|
+
const raw = process.env[exports.ENV_AUTO_START]?.trim().toLowerCase();
|
|
87
|
+
return raw === "1" || raw === "true" || raw === "yes";
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Directories an auto-started `aasm` binary is permitted to live in. The
|
|
91
|
+
* resolved path must be absolute and sit inside one of these install roots,
|
|
92
|
+
* which blocks a `$PATH`-injected `./aasm` (cwd) or a binary planted in an
|
|
93
|
+
* arbitrary writable directory from being spawned. Mirrors the documented
|
|
94
|
+
* install locations (Homebrew, system, user-local, cargo).
|
|
95
|
+
*/
|
|
96
|
+
function allowedInstallDirs() {
|
|
97
|
+
const home = (0, node_os_1.homedir)();
|
|
98
|
+
return [
|
|
99
|
+
"/usr/local/bin",
|
|
100
|
+
"/usr/bin",
|
|
101
|
+
"/opt/homebrew/bin",
|
|
102
|
+
(0, node_path_1.join)(home, ".local", "bin"),
|
|
103
|
+
(0, node_path_1.join)(home, ".cargo", "bin"),
|
|
104
|
+
"/usr/local/cargo/bin",
|
|
105
|
+
];
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Throw {@link ConfigurationError} unless `aasmPath` is an absolute path inside
|
|
109
|
+
* an allow-listed install directory (see {@link allowedInstallDirs}). This is
|
|
110
|
+
* the integrity gate for the auto-start subprocess — without it the SDK would
|
|
111
|
+
* execute whatever `aasm` happened to be first on `$PATH`.
|
|
112
|
+
*/
|
|
113
|
+
function assertAllowedAasmPath(aasmPath) {
|
|
114
|
+
if (!(0, node_path_1.isAbsolute)(aasmPath)) {
|
|
115
|
+
throw new index_js_1.ConfigurationError(`Refusing to auto-start a non-absolute 'aasm' path: ${aasmPath}. ` +
|
|
116
|
+
`Set ${exports.ENV_GATEWAY_URL} to an already-running gateway instead.`);
|
|
117
|
+
}
|
|
118
|
+
const resolved = (0, node_path_1.resolve)(aasmPath);
|
|
119
|
+
const ok = allowedInstallDirs().some((dir) => resolved.startsWith(dir + "/"));
|
|
120
|
+
if (!ok) {
|
|
121
|
+
throw new index_js_1.ConfigurationError(`Refusing to auto-start 'aasm' from an untrusted location: ${resolved}. ` +
|
|
122
|
+
`Install it under one of: ${allowedInstallDirs().join(", ")}, ` +
|
|
123
|
+
`or set ${exports.ENV_GATEWAY_URL} to an already-running gateway.`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Deprecated environment-variable names, kept as backwards-compatible aliases.
|
|
128
|
+
*
|
|
129
|
+
* When one of these supplies a value (and the canonical ``AA_*`` name is unset)
|
|
130
|
+
* a one-time deprecation warning is emitted via ``readEnvWithDeprecation``.
|
|
131
|
+
*/
|
|
132
|
+
exports.LEGACY_ENV_GATEWAY_URL = "AAASM_GATEWAY_URL";
|
|
133
|
+
exports.LEGACY_ENV_API_KEY = "AAASM_API_KEY";
|
|
134
|
+
/**
|
|
135
|
+
* Tracks which legacy env-var names have already produced a deprecation
|
|
136
|
+
* warning so the message is logged at most once per name per process.
|
|
137
|
+
*/
|
|
138
|
+
const _warnedLegacyEnv = new Set();
|
|
139
|
+
/**
|
|
140
|
+
* Read an environment variable preferring the canonical ``AA_*`` name and
|
|
141
|
+
* falling back to a deprecated ``AAASM_*`` alias.
|
|
142
|
+
*
|
|
143
|
+
* Returns ``undefined`` when neither name is set. When the value comes from
|
|
144
|
+
* the legacy alias, a deprecation warning is logged exactly once per legacy
|
|
145
|
+
* name (guarded by ``_warnedLegacyEnv``) directing the user to the canonical
|
|
146
|
+
* name.
|
|
147
|
+
*/
|
|
148
|
+
function readEnvWithDeprecation(canonicalName, legacyName) {
|
|
149
|
+
const canonical = process.env[canonicalName];
|
|
150
|
+
if (canonical)
|
|
151
|
+
return canonical;
|
|
152
|
+
const legacy = process.env[legacyName];
|
|
153
|
+
if (legacy) {
|
|
154
|
+
if (!_warnedLegacyEnv.has(legacyName)) {
|
|
155
|
+
_warnedLegacyEnv.add(legacyName);
|
|
156
|
+
console.warn(`[agent-assembly] ${legacyName} is deprecated and will be removed in a ` +
|
|
157
|
+
`future release. Use ${canonicalName} instead.`);
|
|
158
|
+
}
|
|
159
|
+
return legacy;
|
|
160
|
+
}
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
70
163
|
exports.AASM_AUTO_START_ARGV = ["start", "--mode", "local", "--foreground"];
|
|
71
164
|
/**
|
|
72
165
|
* Return true if a gateway responds with a 2xx status at ``{baseUrl}/healthz``.
|
|
@@ -114,7 +207,11 @@ async function waitForHealthz(baseUrl, timeoutMs = exports.DEFAULT_AUTO_START_TI
|
|
|
114
207
|
return probeHealthz(baseUrl);
|
|
115
208
|
}
|
|
116
209
|
function expandHome(p) {
|
|
117
|
-
|
|
210
|
+
if (!p.startsWith("~")) {
|
|
211
|
+
return p;
|
|
212
|
+
}
|
|
213
|
+
const prefixLength = p.startsWith("~/") ? 2 : 1;
|
|
214
|
+
return (0, node_path_1.resolve)((0, node_os_1.homedir)(), p.slice(prefixLength));
|
|
118
215
|
}
|
|
119
216
|
/**
|
|
120
217
|
* Load ``~/.aasm/config.yaml`` if present.
|
|
@@ -183,7 +280,12 @@ const _seams = {
|
|
|
183
280
|
loadConfigFile: loadConfigFile,
|
|
184
281
|
autoStartGateway: autoStartGateway,
|
|
185
282
|
};
|
|
186
|
-
exports.__testing = {
|
|
283
|
+
exports.__testing = {
|
|
284
|
+
_seams,
|
|
285
|
+
resetLegacyEnvWarnings: () => {
|
|
286
|
+
_warnedLegacyEnv.clear();
|
|
287
|
+
},
|
|
288
|
+
};
|
|
187
289
|
/**
|
|
188
290
|
* Spawn ``aasm start --mode local --foreground`` and wait until ``/healthz``
|
|
189
291
|
* responds.
|
|
@@ -201,6 +303,11 @@ async function autoStartGateway(baseUrl = exports.DEFAULT_GATEWAY_URL, timeoutMs
|
|
|
201
303
|
throw new index_js_1.ConfigurationError(`No gateway found at ${baseUrl} and 'aasm' is not on PATH. ` +
|
|
202
304
|
"Install it with: npm install -g @agent-assembly/cli (or pnpm add -g)");
|
|
203
305
|
}
|
|
306
|
+
// Integrity gate: only spawn an absolute path from an allow-listed install
|
|
307
|
+
// dir, and surface the resolved path so the operator can see exactly which
|
|
308
|
+
// binary the SDK is about to execute.
|
|
309
|
+
assertAllowedAasmPath(aasmPath);
|
|
310
|
+
console.info(`[agent-assembly] auto-starting gateway from ${aasmPath}`);
|
|
204
311
|
_seams.spawnAasm(aasmPath);
|
|
205
312
|
if (!(await waitForHealthz(baseUrl, timeoutMs))) {
|
|
206
313
|
throw new index_js_1.GatewayError(`Auto-started gateway at ${baseUrl} did not become ready ` +
|
|
@@ -218,7 +325,7 @@ async function autoStartGateway(baseUrl = exports.DEFAULT_GATEWAY_URL, timeoutMs
|
|
|
218
325
|
async function resolveGatewayUrl(explicit) {
|
|
219
326
|
if (explicit)
|
|
220
327
|
return explicit;
|
|
221
|
-
const fromEnv =
|
|
328
|
+
const fromEnv = readEnvWithDeprecation(exports.ENV_GATEWAY_URL, exports.LEGACY_ENV_GATEWAY_URL);
|
|
222
329
|
if (fromEnv)
|
|
223
330
|
return fromEnv;
|
|
224
331
|
const config = await _seams.loadConfigFile();
|
|
@@ -231,6 +338,14 @@ async function resolveGatewayUrl(explicit) {
|
|
|
231
338
|
if (await _seams.probeHealthz(exports.DEFAULT_GATEWAY_URL)) {
|
|
232
339
|
return exports.DEFAULT_GATEWAY_URL;
|
|
233
340
|
}
|
|
341
|
+
// Auto-start is opt-in: spawning the local `aasm` binary is a privileged
|
|
342
|
+
// side effect, so a missing gateway is a hard error unless the operator has
|
|
343
|
+
// explicitly enabled AA_AUTO_START.
|
|
344
|
+
if (!autoStartEnabled()) {
|
|
345
|
+
throw new index_js_1.ConfigurationError(`No gateway found at ${exports.DEFAULT_GATEWAY_URL}. Start one with 'aasm start ` +
|
|
346
|
+
`--mode local', set ${exports.ENV_GATEWAY_URL} to a running gateway, or set ` +
|
|
347
|
+
`${exports.ENV_AUTO_START}=1 to allow the SDK to auto-start a local gateway.`);
|
|
348
|
+
}
|
|
234
349
|
await _seams.autoStartGateway(exports.DEFAULT_GATEWAY_URL);
|
|
235
350
|
return exports.DEFAULT_GATEWAY_URL;
|
|
236
351
|
}
|
|
@@ -244,7 +359,7 @@ async function resolveGatewayUrl(explicit) {
|
|
|
244
359
|
async function resolveApiKey(explicit) {
|
|
245
360
|
if (explicit)
|
|
246
361
|
return explicit;
|
|
247
|
-
const fromEnv =
|
|
362
|
+
const fromEnv = readEnvWithDeprecation(exports.ENV_API_KEY, exports.LEGACY_ENV_API_KEY);
|
|
248
363
|
if (fromEnv)
|
|
249
364
|
return fromEnv;
|
|
250
365
|
const config = await _seams.loadConfigFile();
|
|
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ENV_CONTROL_PLANE_URL = exports.ENV_GATEWAY_URL = void 0;
|
|
36
37
|
exports.createClient = createClient;
|
|
37
38
|
exports.detectFrameworks = detectFrameworks;
|
|
38
39
|
exports.registerAdapters = registerAdapters;
|
|
@@ -41,6 +42,7 @@ exports.initAssembly = initAssembly;
|
|
|
41
42
|
const node_module_1 = require("node:module");
|
|
42
43
|
const client_js_1 = require("../gateway/client.js");
|
|
43
44
|
const client_js_2 = require("../native/client.js");
|
|
45
|
+
const index_js_1 = require("../errors/index.js");
|
|
44
46
|
const enforcement_mode_js_1 = require("../types/enforcement-mode.js");
|
|
45
47
|
const ai_sdk_detection_js_1 = require("../hooks/ai-sdk-detection.js");
|
|
46
48
|
const ai_sdk_js_1 = require("../hooks/ai-sdk.js");
|
|
@@ -50,9 +52,13 @@ const mastra_detection_js_1 = require("../hooks/mastra-detection.js");
|
|
|
50
52
|
const mastra_js_1 = require("../hooks/mastra.js");
|
|
51
53
|
const openai_agents_detection_js_1 = require("../hooks/openai-agents-detection.js");
|
|
52
54
|
const openai_agents_js_1 = require("../hooks/openai-agents.js");
|
|
53
|
-
const
|
|
55
|
+
const index_js_2 = require("../lineage/index.js");
|
|
54
56
|
const gateway_resolver_js_1 = require("./gateway-resolver.js");
|
|
55
57
|
const requireFromCwd = (0, node_module_1.createRequire)(`${process.cwd()}/`);
|
|
58
|
+
/** Env-var fallback for ``gatewayUrl`` read at ``initAssembly`` entry. */
|
|
59
|
+
exports.ENV_GATEWAY_URL = "AA_GATEWAY_URL";
|
|
60
|
+
/** Env-var fallback for ``controlPlaneUrl`` read at ``initAssembly`` entry. */
|
|
61
|
+
exports.ENV_CONTROL_PLANE_URL = "AA_CONTROL_PLANE_URL";
|
|
56
62
|
function buildRegistrationEvent(config) {
|
|
57
63
|
const event = { event_type: "register" };
|
|
58
64
|
if (config.parentAgentId !== undefined)
|
|
@@ -71,12 +77,74 @@ function buildRegistrationEvent(config) {
|
|
|
71
77
|
event.enforcement_mode = config.enforcementMode;
|
|
72
78
|
return event;
|
|
73
79
|
}
|
|
74
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Build the {@link RegisterOptions} for the native `register` gRPC call
|
|
82
|
+
* (AAASM-3400) from the resolved config and the detected frameworks. `name`
|
|
83
|
+
* falls back to `agentId`; `framework` is the first detected framework (or
|
|
84
|
+
* `"none"` when running without an adapter); `gatewayEndpoint` is set only when
|
|
85
|
+
* a gateway URL was resolved so the native default endpoint resolution is
|
|
86
|
+
* preserved when it was not. `teamId` / `parentAgentId` carry the agent's
|
|
87
|
+
* team-budget scoping and topology lineage to the gateway (AAASM-3415); each is
|
|
88
|
+
* set only when present so an unset field stays absent.
|
|
89
|
+
*/
|
|
90
|
+
function buildRegisterOptions(config, frameworks) {
|
|
91
|
+
const agentId = config.agentId ?? "";
|
|
92
|
+
return {
|
|
93
|
+
agentId,
|
|
94
|
+
name: config.name ?? agentId,
|
|
95
|
+
framework: frameworks[0] ?? "none",
|
|
96
|
+
...(config.gatewayUrl ? { gatewayEndpoint: config.gatewayUrl } : {}),
|
|
97
|
+
...(config.teamId ? { teamId: config.teamId } : {}),
|
|
98
|
+
...(config.parentAgentId ? { parentAgentId: config.parentAgentId } : {})
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* The only built-in {@link AssemblyMode} for which {@link createClient}
|
|
103
|
+
* constructs a gateway client whose `check()` consults a real authoritative
|
|
104
|
+
* verdict (the native `queryPolicy` against a reachable `aa-runtime`). Every
|
|
105
|
+
* other mode falls back to the allow-all no-op client.
|
|
106
|
+
*/
|
|
107
|
+
const CHECK_CAPABLE_MODE = "napi-inprocess";
|
|
108
|
+
function createClient(config, nativeClientOverride) {
|
|
75
109
|
const mode = config.mode ?? "auto";
|
|
76
110
|
if (config.gatewayClient) {
|
|
77
111
|
return config.gatewayClient;
|
|
78
112
|
}
|
|
79
|
-
|
|
113
|
+
// AAASM-3105 (fail closed): the no-op gateway client's `check()` is allow-all,
|
|
114
|
+
// so registering under live `"enforce"` while routing through it would let a
|
|
115
|
+
// policy-denied action proceed unchecked — a silent fail-open. When the caller
|
|
116
|
+
// explicitly asks for `"enforce"` but supplies no check-capable mode (and no
|
|
117
|
+
// own `gatewayClient`), refuse loudly instead of pretending to enforce. An
|
|
118
|
+
// omitted `enforcementMode` keeps the pre-feature behavior (server-side
|
|
119
|
+
// default), and `"observe"` / `"disabled"` intentionally let actions through.
|
|
120
|
+
if (config.enforcementMode === "enforce" && mode !== CHECK_CAPABLE_MODE) {
|
|
121
|
+
throw new index_js_1.ConfigurationError(`enforcementMode "enforce" requires a check-capable client, but mode "${mode}" ` +
|
|
122
|
+
`routes through the allow-all no-op gateway client, which cannot block a ` +
|
|
123
|
+
`denied action. Use mode "${CHECK_CAPABLE_MODE}", supply your own ` +
|
|
124
|
+
`gatewayClient, or set enforcementMode to "observe"/"disabled".`);
|
|
125
|
+
}
|
|
126
|
+
// HTTP routes use controlPlaneUrl when set, otherwise fall back to the
|
|
127
|
+
// resolved gatewayUrl so pre-feature callers keep their existing base URL.
|
|
128
|
+
const httpBaseUrl = config.controlPlaneUrl ?? config.gatewayUrl;
|
|
129
|
+
// AAASM-3050: in napi-inprocess mode, route `check()` through the native
|
|
130
|
+
// runtime so a reachable aa-runtime's DENY actually blocks a tool. The
|
|
131
|
+
// native primitive fails open when the runtime is absent or slow, and the
|
|
132
|
+
// gateway client swallows local faults, so this never blocks without a
|
|
133
|
+
// runtime — preserving the pre-feature fail-open behavior.
|
|
134
|
+
if (mode === "napi-inprocess") {
|
|
135
|
+
// Reuse the caller-supplied native client when present so the registered
|
|
136
|
+
// session (the one `register()` stored the gateway token on) is the same
|
|
137
|
+
// session `queryPolicy` runs against. Standalone callers (and the routing
|
|
138
|
+
// tests) get a freshly-built client instead.
|
|
139
|
+
const nativeClient = nativeClientOverride ??
|
|
140
|
+
(0, client_js_2.createNativeClient)({
|
|
141
|
+
gateway: config.gatewayUrl ?? "",
|
|
142
|
+
apiKey: config.apiKey ?? "",
|
|
143
|
+
mode: "napi-inprocess"
|
|
144
|
+
});
|
|
145
|
+
return (0, client_js_1.createNativeGatewayClient)(mode, nativeClient, config.agentId, httpBaseUrl);
|
|
146
|
+
}
|
|
147
|
+
return (0, client_js_1.createNoopGatewayClient)(mode, httpBaseUrl);
|
|
80
148
|
}
|
|
81
149
|
function isPackageInstalled(packageName) {
|
|
82
150
|
try {
|
|
@@ -169,7 +237,7 @@ async function patchDetectedVercelAiSdk(client, frameworks, agentId) {
|
|
|
169
237
|
}
|
|
170
238
|
return (0, ai_sdk_js_1.patchVercelAiSdk)({
|
|
171
239
|
gatewayClient: client,
|
|
172
|
-
...(agentId
|
|
240
|
+
...(agentId === undefined ? {} : { agentId })
|
|
173
241
|
});
|
|
174
242
|
}
|
|
175
243
|
async function patchDetectedLangGraph(frameworks, agentId) {
|
|
@@ -190,7 +258,13 @@ async function patchDetectedOpenAIAgents(client, frameworks) {
|
|
|
190
258
|
}
|
|
191
259
|
return (0, openai_agents_js_1.patchOpenAIAgents)({ gatewayClient: client });
|
|
192
260
|
}
|
|
193
|
-
|
|
261
|
+
/**
|
|
262
|
+
* Validate caller-supplied `initAssembly` config, throwing `RangeError` on the
|
|
263
|
+
* two fields that can arrive malformed from non-TS callers (plain JS, JSON
|
|
264
|
+
* config, dynamic input). Extracted to keep `initAssembly` below the cognitive
|
|
265
|
+
* complexity threshold; behaviour-preserving.
|
|
266
|
+
*/
|
|
267
|
+
function validateConfig(config) {
|
|
194
268
|
if (config.delegationReason !== undefined && config.delegationReason.length > 256) {
|
|
195
269
|
throw new RangeError("delegationReason must be <= 256 characters");
|
|
196
270
|
}
|
|
@@ -200,55 +274,112 @@ async function initAssembly(config = {}) {
|
|
|
200
274
|
if (config.enforcementMode !== undefined && !enforcement_mode_js_1.ENFORCEMENT_MODES.includes(config.enforcementMode)) {
|
|
201
275
|
throw new RangeError(`enforcementMode must be one of: ${enforcement_mode_js_1.ENFORCEMENT_MODES.join(", ")} (got: ${String(config.enforcementMode)})`);
|
|
202
276
|
}
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Run every framework detect-and-patch path for the resolved config. Extracted
|
|
280
|
+
* from `initAssembly` to keep its cognitive complexity below threshold;
|
|
281
|
+
* behaviour-preserving (same calls, same order).
|
|
282
|
+
*/
|
|
283
|
+
async function applyFrameworkPatches(config, client, frameworks) {
|
|
284
|
+
const langChainHandler = await registerLangChainHandler(config, client, frameworks);
|
|
285
|
+
const wrappedLangChainTools = await wrapLangChainTools(config, client, frameworks);
|
|
286
|
+
const vercelAiSdkPatched = await patchDetectedVercelAiSdk(client, frameworks, config.agentId);
|
|
287
|
+
const openAIAgentsPatched = await patchDetectedOpenAIAgents(client, frameworks);
|
|
288
|
+
const langGraphPatched = await patchDetectedLangGraph(frameworks, config.agentId);
|
|
289
|
+
const mastraPatched = await patchDetectedMastra(frameworks, config.agentId);
|
|
290
|
+
return {
|
|
291
|
+
langChainHandler,
|
|
292
|
+
wrappedLangChainTools,
|
|
293
|
+
vercelAiSdkPatched,
|
|
294
|
+
openAIAgentsPatched,
|
|
295
|
+
langGraphPatched,
|
|
296
|
+
mastraPatched
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Build the deduped list of active adapter ids from the registered adapters plus
|
|
301
|
+
* whichever framework patches actually took effect. Extracted from
|
|
302
|
+
* `initAssembly` to keep its cognitive complexity below threshold.
|
|
303
|
+
*/
|
|
304
|
+
function buildActiveAdapters(adapters, patches) {
|
|
305
|
+
return [
|
|
306
|
+
...new Set([
|
|
307
|
+
...adapters.map((adapter) => adapter.id),
|
|
308
|
+
...(patches.langChainHandler ? ["langchain-js"] : []),
|
|
309
|
+
...(patches.wrappedLangChainTools.length > 0 ? ["langchain-js"] : []),
|
|
310
|
+
...(patches.vercelAiSdkPatched ? ["vercel-ai-sdk"] : []),
|
|
311
|
+
...(patches.openAIAgentsPatched ? ["openai-agents"] : []),
|
|
312
|
+
...(patches.langGraphPatched ? ["langgraph-js"] : []),
|
|
313
|
+
...(patches.mastraPatched ? ["mastra"] : [])
|
|
314
|
+
])
|
|
315
|
+
];
|
|
316
|
+
}
|
|
317
|
+
async function initAssembly(config = {}) {
|
|
318
|
+
validateConfig(config);
|
|
203
319
|
// Auto-populate parentAgentId from the async context store when not explicitly provided.
|
|
204
320
|
// This allows child agents spawned inside framework hooks to inherit lineage automatically.
|
|
205
|
-
const resolvedParentAgentId = config.parentAgentId ?? (0,
|
|
206
|
-
|
|
321
|
+
const resolvedParentAgentId = config.parentAgentId ?? (0, index_js_2.currentAgentId)();
|
|
322
|
+
// Env-var fallbacks read at entry: explicit config field > env-var > the
|
|
323
|
+
// downstream resolver chain (which may itself error if required and absent).
|
|
324
|
+
const gatewayUrlInput = config.gatewayUrl ?? process.env[exports.ENV_GATEWAY_URL];
|
|
325
|
+
const controlPlaneUrlInput = config.controlPlaneUrl ?? process.env[exports.ENV_CONTROL_PLANE_URL];
|
|
326
|
+
const resolvedGatewayUrl = await (0, gateway_resolver_js_1.resolveGatewayUrl)(gatewayUrlInput);
|
|
207
327
|
const resolvedApiKey = await (0, gateway_resolver_js_1.resolveApiKey)(config.apiKey);
|
|
208
328
|
const resolvedConfig = {
|
|
209
329
|
...config,
|
|
210
330
|
gatewayUrl: resolvedGatewayUrl,
|
|
211
331
|
apiKey: resolvedApiKey,
|
|
332
|
+
...(controlPlaneUrlInput === undefined ? {} : { controlPlaneUrl: controlPlaneUrlInput }),
|
|
212
333
|
...(resolvedParentAgentId ? { parentAgentId: resolvedParentAgentId } : {})
|
|
213
334
|
};
|
|
214
|
-
const client = createClient(resolvedConfig);
|
|
215
335
|
const frameworks = detectFrameworks();
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
//
|
|
219
|
-
//
|
|
336
|
+
// Build the native transport up front (every mode except sdk-only, which has
|
|
337
|
+
// no sidecar) so the same session backs both the gateway client's `check()`
|
|
338
|
+
// and the agent registration — the gateway token `register()` stores on the
|
|
339
|
+
// session is then attached to every subsequent `queryPolicy` request.
|
|
220
340
|
let nativeClient;
|
|
221
341
|
if (resolvedConfig.mode !== "sdk-only") {
|
|
222
342
|
nativeClient = (0, client_js_2.createNativeClient)({
|
|
223
343
|
gateway: resolvedGatewayUrl,
|
|
224
344
|
apiKey: resolvedApiKey,
|
|
225
|
-
mode: resolvedConfig.mode === "napi-inprocess" ? "napi-inprocess" : "grpc-sidecar"
|
|
345
|
+
mode: resolvedConfig.mode === "napi-inprocess" ? "napi-inprocess" : "grpc-sidecar"
|
|
226
346
|
});
|
|
347
|
+
}
|
|
348
|
+
const client = createClient(resolvedConfig, nativeClient);
|
|
349
|
+
const adapters = await registerAdapters(frameworks);
|
|
350
|
+
await startNetworkLayerIfNeeded(client, resolvedConfig);
|
|
351
|
+
if (nativeClient !== undefined) {
|
|
352
|
+
// AAASM-3403: register the agent over the native SDK→gateway gRPC call so
|
|
353
|
+
// the gateway issues a credential token (stored on this session) that
|
|
354
|
+
// unblocks subsequent policy queries. Advisory: a failed registration must
|
|
355
|
+
// not abort init — the agent proceeds unregistered and the proxy / eBPF
|
|
356
|
+
// layers remain authoritative.
|
|
357
|
+
try {
|
|
358
|
+
await nativeClient.register(buildRegisterOptions(resolvedConfig, frameworks));
|
|
359
|
+
}
|
|
360
|
+
catch (error) {
|
|
361
|
+
console.warn(`[agent-assembly] agent registration failed; proceeding unregistered: ${String(error)}`);
|
|
362
|
+
}
|
|
363
|
+
// Topology lineage metadata still flows as an audit event (parent / team /
|
|
364
|
+
// delegation), which `register` does not carry.
|
|
227
365
|
nativeClient.sendEvent(buildRegistrationEvent(resolvedConfig));
|
|
228
366
|
}
|
|
229
|
-
const
|
|
230
|
-
const wrappedLangChainTools = await wrapLangChainTools(resolvedConfig, client, frameworks);
|
|
231
|
-
const vercelAiSdkPatched = await patchDetectedVercelAiSdk(client, frameworks, resolvedConfig.agentId);
|
|
232
|
-
const openAIAgentsPatched = await patchDetectedOpenAIAgents(client, frameworks);
|
|
233
|
-
const langGraphPatched = await patchDetectedLangGraph(frameworks, resolvedConfig.agentId);
|
|
234
|
-
const mastraPatched = await patchDetectedMastra(frameworks, resolvedConfig.agentId);
|
|
367
|
+
const patches = await applyFrameworkPatches(resolvedConfig, client, frameworks);
|
|
235
368
|
return {
|
|
236
|
-
activeAdapters:
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
...(wrappedLangChainTools.length > 0 ? ["langchain-js"] : []),
|
|
241
|
-
...(vercelAiSdkPatched ? ["vercel-ai-sdk"] : []),
|
|
242
|
-
...(openAIAgentsPatched ? ["openai-agents"] : []),
|
|
243
|
-
...(langGraphPatched ? ["langgraph-js"] : []),
|
|
244
|
-
...(mastraPatched ? ["mastra"] : [])
|
|
245
|
-
])
|
|
246
|
-
],
|
|
247
|
-
...(resolvedConfig.parentAgentId !== undefined && { parentAgentId: resolvedConfig.parentAgentId }),
|
|
369
|
+
activeAdapters: buildActiveAdapters(adapters, patches),
|
|
370
|
+
...(resolvedConfig.parentAgentId !== undefined && {
|
|
371
|
+
parentAgentId: resolvedConfig.parentAgentId
|
|
372
|
+
}),
|
|
248
373
|
...(resolvedConfig.teamId !== undefined && { teamId: resolvedConfig.teamId }),
|
|
249
|
-
...(resolvedConfig.delegationReason !== undefined && {
|
|
250
|
-
|
|
251
|
-
|
|
374
|
+
...(resolvedConfig.delegationReason !== undefined && {
|
|
375
|
+
delegationReason: resolvedConfig.delegationReason
|
|
376
|
+
}),
|
|
377
|
+
...(resolvedConfig.spawnedByTool !== undefined && {
|
|
378
|
+
spawnedByTool: resolvedConfig.spawnedByTool
|
|
379
|
+
}),
|
|
380
|
+
...(resolvedConfig.enforcementMode !== undefined && {
|
|
381
|
+
enforcementMode: resolvedConfig.enforcementMode
|
|
382
|
+
}),
|
|
252
383
|
shutdown: async () => {
|
|
253
384
|
for (const adapter of adapters) {
|
|
254
385
|
await adapter.shutdown?.();
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createNoopGatewayClient = createNoopGatewayClient;
|
|
4
|
-
|
|
4
|
+
exports.createNativeGatewayClient = createNativeGatewayClient;
|
|
5
|
+
function createNoopGatewayClient(mode, httpBaseUrl) {
|
|
5
6
|
return {
|
|
6
7
|
mode,
|
|
8
|
+
...(httpBaseUrl === undefined ? {} : { httpBaseUrl }),
|
|
7
9
|
start: async () => undefined,
|
|
8
10
|
close: async () => undefined,
|
|
9
11
|
check: async () => ({ denied: false, pending: false }),
|
|
@@ -13,3 +15,64 @@ function createNoopGatewayClient(mode) {
|
|
|
13
15
|
scanPrompts: async () => undefined
|
|
14
16
|
};
|
|
15
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Translate a governance check request into the native `queryPolicy` query
|
|
20
|
+
* shape (AAASM-3047). The runtime reads `agent_id`, `action_type`, and — for
|
|
21
|
+
* tool calls — `tool_name` / `args`.
|
|
22
|
+
*/
|
|
23
|
+
function toNativeQuery(request, agentId) {
|
|
24
|
+
const query = {
|
|
25
|
+
agent_id: agentId ?? "",
|
|
26
|
+
action_type: request.action
|
|
27
|
+
};
|
|
28
|
+
if (request.toolName !== undefined) {
|
|
29
|
+
query.tool_name = request.toolName;
|
|
30
|
+
}
|
|
31
|
+
if (request.args !== undefined) {
|
|
32
|
+
query.args = request.args;
|
|
33
|
+
}
|
|
34
|
+
return query;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Gateway client backed by the in-process native runtime (AAASM-3050).
|
|
38
|
+
*
|
|
39
|
+
* `check()` asks a reachable `aa-runtime` for an authoritative verdict via the
|
|
40
|
+
* native `queryPolicy` primitive and maps it onto a `GatewayDecision`:
|
|
41
|
+
* - `deny` → `{ denied: true }` (the wrapper throws `PolicyViolationError`)
|
|
42
|
+
* - `pending` → `{ pending: true }` (routes to the approval path)
|
|
43
|
+
* - allow / redact / unspecified → `{ denied: false }`
|
|
44
|
+
*
|
|
45
|
+
* **Fail-open (security-critical):** the SDK is advisory, not a security
|
|
46
|
+
* boundary. The native primitive already returns `allow` when the runtime is
|
|
47
|
+
* unreachable or too slow; on top of that, any local fault while querying is
|
|
48
|
+
* swallowed here and resolves neutral, so a missing or degraded runtime never
|
|
49
|
+
* blocks the agent. The proxy / eBPF layers remain authoritative.
|
|
50
|
+
*/
|
|
51
|
+
function createNativeGatewayClient(mode, nativeClient, agentId, httpBaseUrl) {
|
|
52
|
+
return {
|
|
53
|
+
mode,
|
|
54
|
+
...(httpBaseUrl === undefined ? {} : { httpBaseUrl }),
|
|
55
|
+
start: async () => undefined,
|
|
56
|
+
close: async () => {
|
|
57
|
+
await nativeClient.close();
|
|
58
|
+
},
|
|
59
|
+
check: async (request) => {
|
|
60
|
+
try {
|
|
61
|
+
const verdict = await nativeClient.queryPolicy(toNativeQuery(request, agentId));
|
|
62
|
+
return {
|
|
63
|
+
denied: verdict.denied ?? false,
|
|
64
|
+
pending: verdict.pending ?? false,
|
|
65
|
+
...(verdict.reason === undefined ? {} : { reason: verdict.reason })
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// Fail open: a local fault talking to the runtime must never block.
|
|
70
|
+
return { denied: false, pending: false };
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
waitForApproval: async () => ({ denied: false }),
|
|
74
|
+
record: async () => undefined,
|
|
75
|
+
recordResult: async () => undefined,
|
|
76
|
+
scanPrompts: async () => undefined
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createNoopGatewayClient = void 0;
|
|
3
|
+
exports.createNoopGatewayClient = exports.createNativeGatewayClient = void 0;
|
|
4
4
|
var client_js_1 = require("./client.js");
|
|
5
|
+
Object.defineProperty(exports, "createNativeGatewayClient", { enumerable: true, get: function () { return client_js_1.createNativeGatewayClient; } });
|
|
5
6
|
Object.defineProperty(exports, "createNoopGatewayClient", { enumerable: true, get: function () { return client_js_1.createNoopGatewayClient; } });
|
package/dist/cjs/hooks/ai-sdk.js
CHANGED
|
@@ -52,9 +52,7 @@ function captureOriginalToolFactory(module) {
|
|
|
52
52
|
if (typeof candidate !== "function") {
|
|
53
53
|
return undefined;
|
|
54
54
|
}
|
|
55
|
-
|
|
56
|
-
exports.vercelAiSdkPatchState.originalToolFactory = candidate;
|
|
57
|
-
}
|
|
55
|
+
exports.vercelAiSdkPatchState.originalToolFactory ??= candidate;
|
|
58
56
|
return exports.vercelAiSdkPatchState.originalToolFactory;
|
|
59
57
|
}
|
|
60
58
|
function recordToolResultNonBlocking(gatewayClient, runId, output) {
|
|
@@ -76,7 +74,7 @@ function createWrappedExecute(originalExecute, description, gatewayClient, optio
|
|
|
76
74
|
decision = await gatewayClient.check({
|
|
77
75
|
action: "tool_call",
|
|
78
76
|
toolName: description,
|
|
79
|
-
args
|
|
77
|
+
args,
|
|
80
78
|
runId
|
|
81
79
|
});
|
|
82
80
|
}
|
|
@@ -140,7 +138,7 @@ async function patchVercelAiSdk(options) {
|
|
|
140
138
|
module.tool = createPatchedToolFactory(originalToolFactory, options.gatewayClient, {
|
|
141
139
|
approvalTimeoutMs: options.approvalTimeoutMs ?? 30_000,
|
|
142
140
|
fallbackRunId: options.fallbackRunId ?? "vercel-ai-sdk",
|
|
143
|
-
...(options.agentId
|
|
141
|
+
...(options.agentId === undefined ? {} : { agentId: options.agentId })
|
|
144
142
|
});
|
|
145
143
|
exports.vercelAiSdkPatchState.isPatched = true;
|
|
146
144
|
exports.vercelAiSdkPatchState.patchedModule = module;
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.patchLangChain = patchLangChain;
|
|
4
|
+
/**
|
|
5
|
+
* Intentional no-op stub: native-transport LangChain patching is not
|
|
6
|
+
* implemented. LangChain enforcement is performed in the SDK's callback layer
|
|
7
|
+
* (post-execution redaction) and wrapper layer (pre-execution deny) wired by
|
|
8
|
+
* `initAssembly`, not through this native hook — so there is nothing to patch
|
|
9
|
+
* here yet. Returns `false` (nothing patched) for every mode.
|
|
10
|
+
*
|
|
11
|
+
* The `client` parameter is retained to keep the adapter-registry hook
|
|
12
|
+
* signature (and the public `patchLangChain` export) uniform with the other
|
|
13
|
+
* `patch*` hooks; it is deliberately unused until native patching lands.
|
|
14
|
+
*/
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- stub param kept for signature stability; see TSDoc above
|
|
4
16
|
async function patchLangChain(client) {
|
|
5
|
-
if (client.mode === "grpc-sidecar" || client.mode === "napi-inprocess") {
|
|
6
|
-
return false;
|
|
7
|
-
}
|
|
8
17
|
return false;
|
|
9
18
|
}
|
package/dist/cjs/hooks/mastra.js
CHANGED
|
@@ -75,15 +75,18 @@ async function patchMastra(options) {
|
|
|
75
75
|
exports.mastraPatchState.originalGenerate = originalGenerate;
|
|
76
76
|
exports.mastraPatchState.patchedAgentClass = module.Agent;
|
|
77
77
|
module.Agent.prototype.generate = function patchedGenerate(...args) {
|
|
78
|
-
|
|
78
|
+
// The try guards only the *synchronous* setup (entering the async-context
|
|
79
|
+
// store and invoking the original); the returned promise is handed to the
|
|
80
|
+
// caller, which awaits it, so its rejection is the caller's to handle.
|
|
81
|
+
// Returning it directly (rather than via a local inside the try) avoids an
|
|
82
|
+
// unhandled-rejection footgun without changing timing or call count.
|
|
79
83
|
try {
|
|
80
|
-
|
|
84
|
+
return (0, agent_context_store_js_1.runWithAgentId)(agentId, () => originalGenerate.apply(this, args));
|
|
81
85
|
}
|
|
82
86
|
catch (e) {
|
|
83
87
|
console.warn("[assembly] Mastra lineage patch error on generate; falling back:", e);
|
|
84
88
|
return originalGenerate.apply(this, args);
|
|
85
89
|
}
|
|
86
|
-
return result;
|
|
87
90
|
};
|
|
88
91
|
// Wrap Workflow.prototype.execute if present
|
|
89
92
|
if (module.Workflow?.prototype?.execute) {
|
|
@@ -91,15 +94,16 @@ async function patchMastra(options) {
|
|
|
91
94
|
exports.mastraPatchState.originalExecute = originalExecute;
|
|
92
95
|
exports.mastraPatchState.patchedWorkflowClass = module.Workflow;
|
|
93
96
|
module.Workflow.prototype.execute = function patchedExecute(...args) {
|
|
94
|
-
|
|
97
|
+
// See patchedGenerate above: the try guards only the synchronous setup;
|
|
98
|
+
// the returned promise is awaited by the caller, so returning it directly
|
|
99
|
+
// (not via a local) handles its rejection without altering behaviour.
|
|
95
100
|
try {
|
|
96
|
-
|
|
101
|
+
return (0, agent_context_store_js_1.runWithAgentId)(agentId, () => originalExecute.apply(this, args));
|
|
97
102
|
}
|
|
98
103
|
catch (e) {
|
|
99
104
|
console.warn("[assembly] Mastra lineage patch error on execute; falling back:", e);
|
|
100
105
|
return originalExecute.apply(this, args);
|
|
101
106
|
}
|
|
102
|
-
return result;
|
|
103
107
|
};
|
|
104
108
|
}
|
|
105
109
|
exports.mastraPatchState.isPatched = true;
|
|
@@ -54,9 +54,7 @@ function captureOriginalRunTool(agentClass) {
|
|
|
54
54
|
if (!candidate) {
|
|
55
55
|
return undefined;
|
|
56
56
|
}
|
|
57
|
-
|
|
58
|
-
exports.openAIAgentsPatchState.originalRunTool = candidate;
|
|
59
|
-
}
|
|
57
|
+
exports.openAIAgentsPatchState.originalRunTool ??= candidate;
|
|
60
58
|
return exports.openAIAgentsPatchState.originalRunTool;
|
|
61
59
|
}
|
|
62
60
|
function parseToolCallArguments(toolCall) {
|