@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
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.NativeDisconnectError = exports.NativeQueryPolicyError = exports.NativeSendEventError = exports.NativeConnectError = void 0;
|
|
6
|
+
exports.NativeDisconnectError = exports.NativeRegisterError = exports.NativeQueryPolicyError = exports.NativeSendEventError = exports.NativeConnectError = void 0;
|
|
7
7
|
exports.createNativeClient = createNativeClient;
|
|
8
8
|
const node_module_1 = require("node:module");
|
|
9
9
|
const node_path_1 = __importDefault(require("node:path"));
|
|
@@ -11,6 +11,7 @@ const NATIVE_BINDING_SINGLETON_KEY = Symbol.for("@agent-assembly/sdk/native-bind
|
|
|
11
11
|
const ERROR_CONNECT = "AA_ERR_CONNECT";
|
|
12
12
|
const ERROR_SEND_EVENT = "AA_ERR_SEND_EVENT";
|
|
13
13
|
const ERROR_QUERY_POLICY = "AA_ERR_QUERY_POLICY";
|
|
14
|
+
const ERROR_REGISTER = "AA_ERR_REGISTER";
|
|
14
15
|
const ERROR_DISCONNECT = "AA_ERR_DISCONNECT";
|
|
15
16
|
class NativeConnectError extends Error {
|
|
16
17
|
code = ERROR_CONNECT;
|
|
@@ -24,10 +25,33 @@ class NativeQueryPolicyError extends Error {
|
|
|
24
25
|
code = ERROR_QUERY_POLICY;
|
|
25
26
|
}
|
|
26
27
|
exports.NativeQueryPolicyError = NativeQueryPolicyError;
|
|
28
|
+
class NativeRegisterError extends Error {
|
|
29
|
+
code = ERROR_REGISTER;
|
|
30
|
+
}
|
|
31
|
+
exports.NativeRegisterError = NativeRegisterError;
|
|
27
32
|
class NativeDisconnectError extends Error {
|
|
28
33
|
code = ERROR_DISCONNECT;
|
|
29
34
|
}
|
|
30
35
|
exports.NativeDisconnectError = NativeDisconnectError;
|
|
36
|
+
/**
|
|
37
|
+
* Translate the native `{decision, reason}` verdict into the SDK's
|
|
38
|
+
* `PolicyResult`. Only `"deny"` blocks; `"pending"` routes to the approval
|
|
39
|
+
* path; `"allow"` / `"redact"` / any unrecognized value proceed. This mirrors
|
|
40
|
+
* the shared enforcement contract across the Python / Go / Node SDKs.
|
|
41
|
+
*
|
|
42
|
+
* The native primitive already fails open (returns `"allow"`) when the runtime
|
|
43
|
+
* is unreachable or too slow, so a missing or degraded runtime never blocks.
|
|
44
|
+
*/
|
|
45
|
+
function mapDecisionToPolicyResult(verdict) {
|
|
46
|
+
switch (verdict.decision) {
|
|
47
|
+
case "deny":
|
|
48
|
+
return { denied: true, pending: false, reason: verdict.reason };
|
|
49
|
+
case "pending":
|
|
50
|
+
return { denied: false, pending: true, reason: verdict.reason };
|
|
51
|
+
default:
|
|
52
|
+
return { denied: false, pending: false };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
31
55
|
function mapNativeError(error) {
|
|
32
56
|
if (!(error instanceof Error)) {
|
|
33
57
|
return new Error(String(error));
|
|
@@ -43,6 +67,9 @@ function mapNativeError(error) {
|
|
|
43
67
|
if (code === ERROR_QUERY_POLICY) {
|
|
44
68
|
return new NativeQueryPolicyError(detail);
|
|
45
69
|
}
|
|
70
|
+
if (code === ERROR_REGISTER) {
|
|
71
|
+
return new NativeRegisterError(detail);
|
|
72
|
+
}
|
|
46
73
|
if (code === ERROR_DISCONNECT) {
|
|
47
74
|
return new NativeDisconnectError(detail);
|
|
48
75
|
}
|
|
@@ -51,9 +78,7 @@ function mapNativeError(error) {
|
|
|
51
78
|
function loadNativeBinding() {
|
|
52
79
|
const shouldUseCache = process.env.VITEST !== "true";
|
|
53
80
|
const globalObject = globalThis;
|
|
54
|
-
const cachedBinding = shouldUseCache
|
|
55
|
-
? globalObject[NATIVE_BINDING_SINGLETON_KEY]
|
|
56
|
-
: undefined;
|
|
81
|
+
const cachedBinding = shouldUseCache ? globalObject[NATIVE_BINDING_SINGLETON_KEY] : undefined;
|
|
57
82
|
if (cachedBinding) {
|
|
58
83
|
return cachedBinding;
|
|
59
84
|
}
|
|
@@ -85,7 +110,11 @@ function createNativeClient(options) {
|
|
|
85
110
|
mode,
|
|
86
111
|
close: async () => undefined,
|
|
87
112
|
sendEvent: () => undefined,
|
|
88
|
-
queryPolicy: async () => ({ denied: false, pending: false })
|
|
113
|
+
queryPolicy: async () => ({ denied: false, pending: false }),
|
|
114
|
+
// No native session to register against off the in-process path; the
|
|
115
|
+
// gRPC sidecar registers the agent in its own process. Resolve neutrally
|
|
116
|
+
// so init never blocks on a transport that does not own a handle.
|
|
117
|
+
register: async () => ""
|
|
89
118
|
};
|
|
90
119
|
}
|
|
91
120
|
const binding = loadNativeBinding();
|
|
@@ -94,19 +123,17 @@ function createNativeClient(options) {
|
|
|
94
123
|
let activeHandle;
|
|
95
124
|
let pendingSendError;
|
|
96
125
|
const getHandle = async () => {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
});
|
|
109
|
-
}
|
|
126
|
+
handlePromise ??= binding
|
|
127
|
+
.connect(socketPath)
|
|
128
|
+
.then((handle) => {
|
|
129
|
+
activeHandle = handle;
|
|
130
|
+
return handle;
|
|
131
|
+
})
|
|
132
|
+
.catch((error) => {
|
|
133
|
+
handlePromise = undefined;
|
|
134
|
+
activeHandle = undefined;
|
|
135
|
+
throw mapNativeError(error);
|
|
136
|
+
});
|
|
110
137
|
return handlePromise;
|
|
111
138
|
};
|
|
112
139
|
return {
|
|
@@ -145,18 +172,36 @@ function createNativeClient(options) {
|
|
|
145
172
|
pendingSendError = mapNativeError(error);
|
|
146
173
|
});
|
|
147
174
|
},
|
|
148
|
-
queryPolicy: async () => {
|
|
175
|
+
queryPolicy: async (action) => {
|
|
149
176
|
if (pendingSendError) {
|
|
150
177
|
const error = pendingSendError;
|
|
151
178
|
pendingSendError = undefined;
|
|
152
179
|
throw error;
|
|
153
180
|
}
|
|
154
|
-
//
|
|
155
|
-
//
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
|
|
159
|
-
|
|
181
|
+
// Connect (surfacing any connect error as a genuine local fault), then
|
|
182
|
+
// ask the runtime for an authoritative verdict via the native primitive.
|
|
183
|
+
// The native `queryPolicy` is async — it offloads its blocking wait to a
|
|
184
|
+
// worker thread, so awaiting it never blocks the Node event loop — and it
|
|
185
|
+
// already fails open (returns `"allow"`) when the runtime is unreachable
|
|
186
|
+
// or too slow, so a missing or degraded runtime never blocks the agent.
|
|
187
|
+
const handle = await getHandle();
|
|
188
|
+
const verdict = await binding.queryPolicy(handle, action);
|
|
189
|
+
return mapDecisionToPolicyResult(verdict);
|
|
190
|
+
},
|
|
191
|
+
register: async (options) => {
|
|
192
|
+
// Register on the same session the queryPolicy path uses, so the token
|
|
193
|
+
// the gateway issues is stored on this handle and attached to every
|
|
194
|
+
// subsequent query. This is the only direct SDK→gateway gRPC call
|
|
195
|
+
// (ADR 0004); CheckAction still flows through aa-runtime.
|
|
196
|
+
if (binding.register === undefined) {
|
|
197
|
+
// A binding without `register` predates AAASM-3400; the agent simply
|
|
198
|
+
// runs unregistered rather than failing init.
|
|
199
|
+
return "";
|
|
200
|
+
}
|
|
201
|
+
const handle = await getHandle();
|
|
202
|
+
return binding.register(handle, options).catch((error) => {
|
|
203
|
+
throw mapNativeError(error);
|
|
204
|
+
});
|
|
160
205
|
}
|
|
161
206
|
};
|
|
162
207
|
}
|
package/dist/cjs/op-control.js
CHANGED
|
@@ -22,9 +22,63 @@
|
|
|
22
22
|
*/
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
24
|
exports.OpControlSubscriber = void 0;
|
|
25
|
+
exports.gatewayHostOf = gatewayHostOf;
|
|
26
|
+
exports.resolveOpControlCredentials = resolveOpControlCredentials;
|
|
25
27
|
const grpc_js_1 = require("@grpc/grpc-js");
|
|
26
28
|
const op_terminated_error_js_1 = require("./errors/op-terminated-error.js");
|
|
27
29
|
const policy_js_1 = require("./proto/generated/policy.js");
|
|
30
|
+
/**
|
|
31
|
+
* Hosts treated as loopback for the secure-by-default transport decision.
|
|
32
|
+
* A loopback gateway is the local dev-mode CP, where plaintext gRPC is the
|
|
33
|
+
* documented default; anything else is presumed remote and must be encrypted.
|
|
34
|
+
*/
|
|
35
|
+
const LOOPBACK_HOSTS = new Set(["localhost", "127.0.0.1", "::1", "[::1]"]);
|
|
36
|
+
/**
|
|
37
|
+
* Extract the bare host from a gRPC target (`host:port`, a bare host, or a
|
|
38
|
+
* URL-style `scheme://host:port`). Returns the lowercased host with any
|
|
39
|
+
* surrounding IPv6 brackets preserved so it can be matched against
|
|
40
|
+
* {@link LOOPBACK_HOSTS}.
|
|
41
|
+
*/
|
|
42
|
+
function gatewayHostOf(gatewayUrl) {
|
|
43
|
+
let target = gatewayUrl.trim();
|
|
44
|
+
const schemeIdx = target.indexOf("://");
|
|
45
|
+
if (schemeIdx !== -1)
|
|
46
|
+
target = target.slice(schemeIdx + 3);
|
|
47
|
+
// Drop a path/query suffix if a URL form was passed.
|
|
48
|
+
const slashIdx = target.indexOf("/");
|
|
49
|
+
if (slashIdx !== -1)
|
|
50
|
+
target = target.slice(0, slashIdx);
|
|
51
|
+
if (target.startsWith("[")) {
|
|
52
|
+
// Bracketed IPv6: keep the bracketed form, strip only the trailing :port.
|
|
53
|
+
const close = target.indexOf("]");
|
|
54
|
+
return close === -1 ? target.toLowerCase() : target.slice(0, close + 1).toLowerCase();
|
|
55
|
+
}
|
|
56
|
+
const colonIdx = target.indexOf(":");
|
|
57
|
+
if (colonIdx !== -1)
|
|
58
|
+
target = target.slice(0, colonIdx);
|
|
59
|
+
return target.toLowerCase();
|
|
60
|
+
}
|
|
61
|
+
function isLoopbackTarget(gatewayUrl) {
|
|
62
|
+
return LOOPBACK_HOSTS.has(gatewayHostOf(gatewayUrl));
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Pick channel credentials for the op-control stream, secure by default.
|
|
66
|
+
*
|
|
67
|
+
* Precedence: an explicit `credentials` override wins; otherwise a loopback
|
|
68
|
+
* target gets plaintext (local dev gateway), a remote target gets TLS, and a
|
|
69
|
+
* remote target is only allowed plaintext when the caller sets `allowInsecure`.
|
|
70
|
+
*
|
|
71
|
+
* @throws never — returns the chosen {@link ChannelCredentials}.
|
|
72
|
+
*/
|
|
73
|
+
function resolveOpControlCredentials(gatewayUrl, opts) {
|
|
74
|
+
if (opts.credentials)
|
|
75
|
+
return opts.credentials;
|
|
76
|
+
if (isLoopbackTarget(gatewayUrl))
|
|
77
|
+
return grpc_js_1.credentials.createInsecure();
|
|
78
|
+
if (opts.allowInsecure)
|
|
79
|
+
return grpc_js_1.credentials.createInsecure();
|
|
80
|
+
return grpc_js_1.credentials.createSsl();
|
|
81
|
+
}
|
|
28
82
|
class OpControlSubscriber {
|
|
29
83
|
client;
|
|
30
84
|
agent;
|
|
@@ -44,7 +98,7 @@ class OpControlSubscriber {
|
|
|
44
98
|
};
|
|
45
99
|
const client = opts.clientFactory
|
|
46
100
|
? opts.clientFactory()
|
|
47
|
-
: new policy_js_1.PolicyServiceClient(gatewayUrl, opts
|
|
101
|
+
: new policy_js_1.PolicyServiceClient(gatewayUrl, resolveOpControlCredentials(gatewayUrl, opts));
|
|
48
102
|
const subscriber = new OpControlSubscriber(client, agent);
|
|
49
103
|
subscriber.start();
|
|
50
104
|
return subscriber;
|
package/dist/cjs/runtime.js
CHANGED
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
* flow with `import { initAssembly } from "@agent-assembly/sdk/runtime"`.
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.INSTALL_HINT = exports.RUNTIME_SUBPACKAGE = exports.RUNTIME_LOG_FILENAME = exports.DOCKER_BASE_BIN = exports.USER_LOCAL_BIN = exports.DEFAULT_RUNTIME_HOST = exports.DEFAULT_PORT = exports.BINARY_NAME = void 0;
|
|
12
|
+
exports.INSTALL_HINT = exports.RUNTIME_SUBPACKAGE = exports.RUNTIME_LOG_FILENAME = exports.DOCKER_BASE_BIN = exports.USER_LOCAL_BIN = exports.ENV_AUTO_START = exports.DEFAULT_RUNTIME_HOST = exports.DEFAULT_PORT = exports.BINARY_NAME = void 0;
|
|
13
13
|
exports.findAasmBinary = findAasmBinary;
|
|
14
14
|
exports.isRunning = isRunning;
|
|
15
|
+
exports.assertSafeBinaryPath = assertSafeBinaryPath;
|
|
15
16
|
exports.startRuntime = startRuntime;
|
|
16
17
|
exports.initAssembly = initAssembly;
|
|
17
18
|
const node_child_process_1 = require("node:child_process");
|
|
@@ -24,6 +25,13 @@ const node_process_1 = require("node:process");
|
|
|
24
25
|
exports.BINARY_NAME = "aasm";
|
|
25
26
|
exports.DEFAULT_PORT = 7878;
|
|
26
27
|
exports.DEFAULT_RUNTIME_HOST = "127.0.0.1";
|
|
28
|
+
/**
|
|
29
|
+
* Opt-in gate for spawning the `aasm` sidecar. Auto-start runs a binary
|
|
30
|
+
* discovered from `$PATH` / the filesystem, so it is a privileged side effect
|
|
31
|
+
* that must be explicitly enabled rather than triggered silently by every
|
|
32
|
+
* `initAssembly()` call. Set to `1`/`true`/`yes` to permit auto-start.
|
|
33
|
+
*/
|
|
34
|
+
exports.ENV_AUTO_START = "AA_AUTO_START";
|
|
27
35
|
exports.USER_LOCAL_BIN = (0, node_path_1.join)((0, node_os_1.homedir)(), ".local", "bin");
|
|
28
36
|
exports.DOCKER_BASE_BIN = "/usr/local/bin";
|
|
29
37
|
exports.RUNTIME_LOG_FILENAME = ".aasm-runtime.log";
|
|
@@ -100,6 +108,51 @@ function isRunning(port = exports.DEFAULT_PORT, host = exports.DEFAULT_RUNTIME_H
|
|
|
100
108
|
socket.once("error", () => settle(false));
|
|
101
109
|
});
|
|
102
110
|
}
|
|
111
|
+
/** Truthy values that enable {@link ENV_AUTO_START}. */
|
|
112
|
+
function autoStartEnabled() {
|
|
113
|
+
const raw = node_process_1.env[exports.ENV_AUTO_START]?.trim().toLowerCase();
|
|
114
|
+
return raw === "1" || raw === "true" || raw === "yes";
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Install roots an auto-started `aasm` binary is permitted to live in, in
|
|
118
|
+
* addition to the npm-bundled `node_modules/@agent-assembly/runtime-*` path
|
|
119
|
+
* (which is trusted because it ships with the SDK install). This blocks a
|
|
120
|
+
* `$PATH`-injected `./aasm` or a binary planted in an arbitrary writable
|
|
121
|
+
* directory from being spawned.
|
|
122
|
+
*/
|
|
123
|
+
function allowedInstallDirs() {
|
|
124
|
+
const home = (0, node_os_1.homedir)();
|
|
125
|
+
return [
|
|
126
|
+
"/usr/local/bin",
|
|
127
|
+
"/usr/bin",
|
|
128
|
+
"/opt/homebrew/bin",
|
|
129
|
+
exports.USER_LOCAL_BIN,
|
|
130
|
+
(0, node_path_1.join)(home, ".cargo", "bin"),
|
|
131
|
+
"/usr/local/cargo/bin",
|
|
132
|
+
exports.DOCKER_BASE_BIN,
|
|
133
|
+
];
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Throw `Error` unless `binaryPath` is safe to spawn: it must be absolute and
|
|
137
|
+
* either resolve inside an allow-listed install dir (see
|
|
138
|
+
* {@link allowedInstallDirs}) or be the npm-bundled runtime binary. This is the
|
|
139
|
+
* integrity gate for the auto-start subprocess — without it the SDK would
|
|
140
|
+
* execute whatever `aasm` happened to be first on `$PATH`.
|
|
141
|
+
*/
|
|
142
|
+
function assertSafeBinaryPath(binaryPath) {
|
|
143
|
+
if (!(0, node_path_1.isAbsolute)(binaryPath)) {
|
|
144
|
+
throw new Error(`Refusing to auto-start a non-absolute 'aasm' path: ${binaryPath}`);
|
|
145
|
+
}
|
|
146
|
+
const resolved = (0, node_path_1.resolve)(binaryPath);
|
|
147
|
+
const bundled = bundledRuntimeBinaryPath();
|
|
148
|
+
if (bundled !== null && (0, node_path_1.resolve)(bundled) === resolved)
|
|
149
|
+
return;
|
|
150
|
+
const ok = allowedInstallDirs().some((dir) => resolved.startsWith((0, node_path_1.resolve)(dir) + "/"));
|
|
151
|
+
if (!ok) {
|
|
152
|
+
throw new Error(`Refusing to auto-start 'aasm' from an untrusted location: ${resolved}. ` +
|
|
153
|
+
`Install it under one of: ${allowedInstallDirs().join(", ")}.`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
103
156
|
/**
|
|
104
157
|
* Spawn `aasm serve --port <port>` as a detached background subprocess.
|
|
105
158
|
*
|
|
@@ -126,19 +179,32 @@ function startRuntime(binaryPath, port = exports.DEFAULT_PORT, logDir = (0, node
|
|
|
126
179
|
* 2. Resolve the binary via {@link findAasmBinary}.
|
|
127
180
|
* 3. Spawn the sidecar via {@link startRuntime}.
|
|
128
181
|
*
|
|
129
|
-
* `
|
|
130
|
-
*
|
|
131
|
-
* `@agent-assembly/sdk` `initAssembly`
|
|
182
|
+
* `_agentId` is accepted to keep the ticket-specified signature stable but is
|
|
183
|
+
* intentionally not consumed at this lifecycle layer; actual register-and-connect
|
|
184
|
+
* is performed by the existing gateway-aware `@agent-assembly/sdk` `initAssembly`
|
|
185
|
+
* once the sidecar is reachable.
|
|
186
|
+
*
|
|
187
|
+
* Auto-start is **opt-in**: when the sidecar is not already running, this
|
|
188
|
+
* throws unless `AA_AUTO_START` is enabled. When it does spawn, the resolved
|
|
189
|
+
* binary path is logged and integrity-checked via {@link assertSafeBinaryPath}.
|
|
132
190
|
*
|
|
133
|
-
* Throws `Error` with {@link INSTALL_HINT} when no binary is found
|
|
191
|
+
* Throws `Error` with {@link INSTALL_HINT} when no binary is found, and a
|
|
192
|
+
* descriptive `Error` when auto-start is not opted in or the resolved binary
|
|
193
|
+
* fails the integrity check.
|
|
134
194
|
*/
|
|
135
|
-
async function initAssembly(
|
|
136
|
-
void agentId; // not consumed at the lifecycle layer; see jsdoc
|
|
195
|
+
async function initAssembly(_agentId, port = exports.DEFAULT_PORT) {
|
|
137
196
|
if (await isRunning(port))
|
|
138
197
|
return;
|
|
198
|
+
if (!autoStartEnabled()) {
|
|
199
|
+
throw new Error(`No aasm sidecar running on port ${port} and auto-start is disabled. ` +
|
|
200
|
+
`Start it with 'aasm serve --port ${port}', or set ${exports.ENV_AUTO_START}=1 ` +
|
|
201
|
+
"to allow the SDK to auto-start it.");
|
|
202
|
+
}
|
|
139
203
|
const binary = findAasmBinary();
|
|
140
204
|
if (binary === null) {
|
|
141
205
|
throw new Error(exports.INSTALL_HINT);
|
|
142
206
|
}
|
|
207
|
+
assertSafeBinaryPath(binary);
|
|
208
|
+
console.info(`[agent-assembly] auto-starting aasm sidecar from ${binary}`);
|
|
143
209
|
startRuntime(binary, port);
|
|
144
210
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { existsSync, readFileSync } from "node:fs";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
|
-
import { join, resolve as resolvePath } from "node:path";
|
|
4
|
+
import { isAbsolute, join, resolve as resolvePath } from "node:path";
|
|
5
5
|
import { ConfigurationError, GatewayError } from "../errors/index.js";
|
|
6
6
|
/**
|
|
7
7
|
* Resolve the gateway URL and API key for ``initAssembly``.
|
|
@@ -14,17 +14,109 @@ import { ConfigurationError, GatewayError } from "../errors/index.js";
|
|
|
14
14
|
* Resolution precedence (highest first):
|
|
15
15
|
*
|
|
16
16
|
* 1. Explicit field on the AssemblyConfig
|
|
17
|
-
* 2. Environment variable
|
|
17
|
+
* 2. Environment variable — canonical ``AA_GATEWAY_URL`` / ``AA_API_KEY``,
|
|
18
|
+
* with the legacy ``AAASM_GATEWAY_URL`` / ``AAASM_API_KEY`` names accepted
|
|
19
|
+
* as deprecated aliases (a one-time warning is logged when a legacy name
|
|
20
|
+
* supplies the value)
|
|
18
21
|
* 3. Config file (~/.aasm/config.yaml, optional js-yaml soft dep)
|
|
19
|
-
* 4. Local default: probe http://localhost:7391, auto-start
|
|
22
|
+
* 4. Local default: probe http://localhost:7391; when absent, auto-start the
|
|
23
|
+
* local `aasm` gateway ONLY if `AA_AUTO_START` is opted in and the binary
|
|
24
|
+
* resolves to an allow-listed install dir — otherwise raise an error.
|
|
20
25
|
*/
|
|
21
26
|
export const DEFAULT_GATEWAY_URL = "http://localhost:7391";
|
|
22
27
|
export const DEFAULT_HEALTHZ_PATH = "/healthz";
|
|
23
28
|
export const DEFAULT_PROBE_TIMEOUT_MS = 500;
|
|
24
29
|
export const DEFAULT_AUTO_START_TIMEOUT_MS = 5000;
|
|
25
30
|
export const DEFAULT_CONFIG_FILE_PATH = "~/.aasm/config.yaml";
|
|
26
|
-
export const ENV_GATEWAY_URL = "
|
|
27
|
-
export const ENV_API_KEY = "
|
|
31
|
+
export const ENV_GATEWAY_URL = "AA_GATEWAY_URL";
|
|
32
|
+
export const ENV_API_KEY = "AA_API_KEY";
|
|
33
|
+
/**
|
|
34
|
+
* Opt-in gate for auto-starting a local gateway. Auto-start spawns the `aasm`
|
|
35
|
+
* binary resolved from `$PATH`, so it is gated behind an explicit opt-in rather
|
|
36
|
+
* than running silently: a `$PATH` entry an attacker can write to would
|
|
37
|
+
* otherwise be executed by any process that calls `initAssembly()`. Set to
|
|
38
|
+
* `1`/`true`/`yes` to permit auto-start.
|
|
39
|
+
*/
|
|
40
|
+
export const ENV_AUTO_START = "AA_AUTO_START";
|
|
41
|
+
/** Truthy values that enable {@link ENV_AUTO_START}. */
|
|
42
|
+
function autoStartEnabled() {
|
|
43
|
+
const raw = process.env[ENV_AUTO_START]?.trim().toLowerCase();
|
|
44
|
+
return raw === "1" || raw === "true" || raw === "yes";
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Directories an auto-started `aasm` binary is permitted to live in. The
|
|
48
|
+
* resolved path must be absolute and sit inside one of these install roots,
|
|
49
|
+
* which blocks a `$PATH`-injected `./aasm` (cwd) or a binary planted in an
|
|
50
|
+
* arbitrary writable directory from being spawned. Mirrors the documented
|
|
51
|
+
* install locations (Homebrew, system, user-local, cargo).
|
|
52
|
+
*/
|
|
53
|
+
function allowedInstallDirs() {
|
|
54
|
+
const home = homedir();
|
|
55
|
+
return [
|
|
56
|
+
"/usr/local/bin",
|
|
57
|
+
"/usr/bin",
|
|
58
|
+
"/opt/homebrew/bin",
|
|
59
|
+
join(home, ".local", "bin"),
|
|
60
|
+
join(home, ".cargo", "bin"),
|
|
61
|
+
"/usr/local/cargo/bin",
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Throw {@link ConfigurationError} unless `aasmPath` is an absolute path inside
|
|
66
|
+
* an allow-listed install directory (see {@link allowedInstallDirs}). This is
|
|
67
|
+
* the integrity gate for the auto-start subprocess — without it the SDK would
|
|
68
|
+
* execute whatever `aasm` happened to be first on `$PATH`.
|
|
69
|
+
*/
|
|
70
|
+
export function assertAllowedAasmPath(aasmPath) {
|
|
71
|
+
if (!isAbsolute(aasmPath)) {
|
|
72
|
+
throw new ConfigurationError(`Refusing to auto-start a non-absolute 'aasm' path: ${aasmPath}. ` +
|
|
73
|
+
`Set ${ENV_GATEWAY_URL} to an already-running gateway instead.`);
|
|
74
|
+
}
|
|
75
|
+
const resolved = resolvePath(aasmPath);
|
|
76
|
+
const ok = allowedInstallDirs().some((dir) => resolved.startsWith(dir + "/"));
|
|
77
|
+
if (!ok) {
|
|
78
|
+
throw new ConfigurationError(`Refusing to auto-start 'aasm' from an untrusted location: ${resolved}. ` +
|
|
79
|
+
`Install it under one of: ${allowedInstallDirs().join(", ")}, ` +
|
|
80
|
+
`or set ${ENV_GATEWAY_URL} to an already-running gateway.`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Deprecated environment-variable names, kept as backwards-compatible aliases.
|
|
85
|
+
*
|
|
86
|
+
* When one of these supplies a value (and the canonical ``AA_*`` name is unset)
|
|
87
|
+
* a one-time deprecation warning is emitted via ``readEnvWithDeprecation``.
|
|
88
|
+
*/
|
|
89
|
+
export const LEGACY_ENV_GATEWAY_URL = "AAASM_GATEWAY_URL";
|
|
90
|
+
export const LEGACY_ENV_API_KEY = "AAASM_API_KEY";
|
|
91
|
+
/**
|
|
92
|
+
* Tracks which legacy env-var names have already produced a deprecation
|
|
93
|
+
* warning so the message is logged at most once per name per process.
|
|
94
|
+
*/
|
|
95
|
+
const _warnedLegacyEnv = new Set();
|
|
96
|
+
/**
|
|
97
|
+
* Read an environment variable preferring the canonical ``AA_*`` name and
|
|
98
|
+
* falling back to a deprecated ``AAASM_*`` alias.
|
|
99
|
+
*
|
|
100
|
+
* Returns ``undefined`` when neither name is set. When the value comes from
|
|
101
|
+
* the legacy alias, a deprecation warning is logged exactly once per legacy
|
|
102
|
+
* name (guarded by ``_warnedLegacyEnv``) directing the user to the canonical
|
|
103
|
+
* name.
|
|
104
|
+
*/
|
|
105
|
+
function readEnvWithDeprecation(canonicalName, legacyName) {
|
|
106
|
+
const canonical = process.env[canonicalName];
|
|
107
|
+
if (canonical)
|
|
108
|
+
return canonical;
|
|
109
|
+
const legacy = process.env[legacyName];
|
|
110
|
+
if (legacy) {
|
|
111
|
+
if (!_warnedLegacyEnv.has(legacyName)) {
|
|
112
|
+
_warnedLegacyEnv.add(legacyName);
|
|
113
|
+
console.warn(`[agent-assembly] ${legacyName} is deprecated and will be removed in a ` +
|
|
114
|
+
`future release. Use ${canonicalName} instead.`);
|
|
115
|
+
}
|
|
116
|
+
return legacy;
|
|
117
|
+
}
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
28
120
|
export const AASM_AUTO_START_ARGV = ["start", "--mode", "local", "--foreground"];
|
|
29
121
|
/**
|
|
30
122
|
* Return true if a gateway responds with a 2xx status at ``{baseUrl}/healthz``.
|
|
@@ -72,7 +164,11 @@ export async function waitForHealthz(baseUrl, timeoutMs = DEFAULT_AUTO_START_TIM
|
|
|
72
164
|
return probeHealthz(baseUrl);
|
|
73
165
|
}
|
|
74
166
|
function expandHome(p) {
|
|
75
|
-
|
|
167
|
+
if (!p.startsWith("~")) {
|
|
168
|
+
return p;
|
|
169
|
+
}
|
|
170
|
+
const prefixLength = p.startsWith("~/") ? 2 : 1;
|
|
171
|
+
return resolvePath(homedir(), p.slice(prefixLength));
|
|
76
172
|
}
|
|
77
173
|
/**
|
|
78
174
|
* Load ``~/.aasm/config.yaml`` if present.
|
|
@@ -141,7 +237,12 @@ const _seams = {
|
|
|
141
237
|
loadConfigFile: loadConfigFile,
|
|
142
238
|
autoStartGateway: autoStartGateway,
|
|
143
239
|
};
|
|
144
|
-
export const __testing = {
|
|
240
|
+
export const __testing = {
|
|
241
|
+
_seams,
|
|
242
|
+
resetLegacyEnvWarnings: () => {
|
|
243
|
+
_warnedLegacyEnv.clear();
|
|
244
|
+
},
|
|
245
|
+
};
|
|
145
246
|
/**
|
|
146
247
|
* Spawn ``aasm start --mode local --foreground`` and wait until ``/healthz``
|
|
147
248
|
* responds.
|
|
@@ -159,6 +260,11 @@ export async function autoStartGateway(baseUrl = DEFAULT_GATEWAY_URL, timeoutMs
|
|
|
159
260
|
throw new ConfigurationError(`No gateway found at ${baseUrl} and 'aasm' is not on PATH. ` +
|
|
160
261
|
"Install it with: npm install -g @agent-assembly/cli (or pnpm add -g)");
|
|
161
262
|
}
|
|
263
|
+
// Integrity gate: only spawn an absolute path from an allow-listed install
|
|
264
|
+
// dir, and surface the resolved path so the operator can see exactly which
|
|
265
|
+
// binary the SDK is about to execute.
|
|
266
|
+
assertAllowedAasmPath(aasmPath);
|
|
267
|
+
console.info(`[agent-assembly] auto-starting gateway from ${aasmPath}`);
|
|
162
268
|
_seams.spawnAasm(aasmPath);
|
|
163
269
|
if (!(await waitForHealthz(baseUrl, timeoutMs))) {
|
|
164
270
|
throw new GatewayError(`Auto-started gateway at ${baseUrl} did not become ready ` +
|
|
@@ -176,7 +282,7 @@ export async function autoStartGateway(baseUrl = DEFAULT_GATEWAY_URL, timeoutMs
|
|
|
176
282
|
export async function resolveGatewayUrl(explicit) {
|
|
177
283
|
if (explicit)
|
|
178
284
|
return explicit;
|
|
179
|
-
const fromEnv =
|
|
285
|
+
const fromEnv = readEnvWithDeprecation(ENV_GATEWAY_URL, LEGACY_ENV_GATEWAY_URL);
|
|
180
286
|
if (fromEnv)
|
|
181
287
|
return fromEnv;
|
|
182
288
|
const config = await _seams.loadConfigFile();
|
|
@@ -189,6 +295,14 @@ export async function resolveGatewayUrl(explicit) {
|
|
|
189
295
|
if (await _seams.probeHealthz(DEFAULT_GATEWAY_URL)) {
|
|
190
296
|
return DEFAULT_GATEWAY_URL;
|
|
191
297
|
}
|
|
298
|
+
// Auto-start is opt-in: spawning the local `aasm` binary is a privileged
|
|
299
|
+
// side effect, so a missing gateway is a hard error unless the operator has
|
|
300
|
+
// explicitly enabled AA_AUTO_START.
|
|
301
|
+
if (!autoStartEnabled()) {
|
|
302
|
+
throw new ConfigurationError(`No gateway found at ${DEFAULT_GATEWAY_URL}. Start one with 'aasm start ` +
|
|
303
|
+
`--mode local', set ${ENV_GATEWAY_URL} to a running gateway, or set ` +
|
|
304
|
+
`${ENV_AUTO_START}=1 to allow the SDK to auto-start a local gateway.`);
|
|
305
|
+
}
|
|
192
306
|
await _seams.autoStartGateway(DEFAULT_GATEWAY_URL);
|
|
193
307
|
return DEFAULT_GATEWAY_URL;
|
|
194
308
|
}
|
|
@@ -202,7 +316,7 @@ export async function resolveGatewayUrl(explicit) {
|
|
|
202
316
|
export async function resolveApiKey(explicit) {
|
|
203
317
|
if (explicit)
|
|
204
318
|
return explicit;
|
|
205
|
-
const fromEnv =
|
|
319
|
+
const fromEnv = readEnvWithDeprecation(ENV_API_KEY, LEGACY_ENV_API_KEY);
|
|
206
320
|
if (fromEnv)
|
|
207
321
|
return fromEnv;
|
|
208
322
|
const config = await _seams.loadConfigFile();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway-resolver.js","sourceRoot":"","sources":["../../../src/core/gateway-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"gateway-resolver.js","sourceRoot":"","sources":["../../../src/core/gateway-resolver.ts"],"names":[],"mappings":"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"}
|