@aexhq/sdk 0.38.1 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -17
- package/dist/_contracts/api-key.d.ts +49 -0
- package/dist/_contracts/api-key.js +87 -0
- package/dist/_contracts/bundle-manifest.d.ts +86 -0
- package/dist/_contracts/bundle-manifest.js +157 -0
- package/dist/_contracts/error-codes.d.ts +26 -0
- package/dist/_contracts/error-codes.js +79 -0
- package/dist/_contracts/error-factory.d.ts +32 -0
- package/dist/_contracts/error-factory.js +142 -0
- package/dist/_contracts/event-envelope.d.ts +33 -10
- package/dist/_contracts/event-envelope.js +46 -10
- package/dist/_contracts/event-view.d.ts +123 -0
- package/dist/_contracts/event-view.js +120 -0
- package/dist/_contracts/http.js +12 -3
- package/dist/_contracts/index.d.ts +8 -4
- package/dist/_contracts/index.js +11 -7
- package/dist/_contracts/models.d.ts +15 -0
- package/dist/_contracts/models.js +33 -0
- package/dist/_contracts/operations.d.ts +70 -2
- package/dist/_contracts/operations.js +143 -7
- package/dist/_contracts/run-config.d.ts +35 -10
- package/dist/_contracts/run-config.js +17 -5
- package/dist/_contracts/run-record.d.ts +3 -2
- package/dist/_contracts/runtime-types.d.ts +148 -36
- package/dist/_contracts/runtime-types.js +33 -1
- package/dist/_contracts/sdk-errors.d.ts +61 -2
- package/dist/_contracts/sdk-errors.js +83 -3
- package/dist/_contracts/sdk-secrets.js +31 -6
- package/dist/_contracts/stable.d.ts +14 -0
- package/dist/_contracts/stable.js +14 -0
- package/dist/_contracts/status.d.ts +28 -1
- package/dist/_contracts/status.js +48 -3
- package/dist/_contracts/submission.d.ts +157 -14
- package/dist/_contracts/submission.js +319 -55
- package/dist/_contracts/suggest.d.ts +15 -0
- package/dist/_contracts/suggest.js +54 -0
- package/dist/asset-upload.d.ts +27 -1
- package/dist/asset-upload.js +219 -4
- package/dist/asset-upload.js.map +1 -1
- package/dist/bundle.d.ts +23 -14
- package/dist/bundle.js +39 -20
- package/dist/bundle.js.map +1 -1
- package/dist/canonical-zip.d.ts +68 -0
- package/dist/canonical-zip.js +307 -0
- package/dist/canonical-zip.js.map +1 -0
- package/dist/cli.mjs +1927 -326
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/client.d.ts +273 -70
- package/dist/client.js +885 -335
- package/dist/client.js.map +1 -1
- package/dist/fetch-archive.js +14 -14
- package/dist/fetch-archive.js.map +1 -1
- package/dist/file.d.ts +33 -6
- package/dist/file.js +120 -54
- package/dist/file.js.map +1 -1
- package/dist/index.d.ts +23 -14
- package/dist/index.js +31 -14
- package/dist/index.js.map +1 -1
- package/dist/node-fs.d.ts +26 -9
- package/dist/node-fs.js +13 -38
- package/dist/node-fs.js.map +1 -1
- package/dist/node-walk.d.ts +69 -0
- package/dist/node-walk.js +146 -0
- package/dist/node-walk.js.map +1 -0
- package/dist/retry.d.ts +9 -13
- package/dist/retry.js +18 -17
- package/dist/retry.js.map +1 -1
- package/dist/skill.d.ts +151 -0
- package/dist/skill.js +298 -0
- package/dist/skill.js.map +1 -0
- package/dist/tool.d.ts +14 -2
- package/dist/tool.js +33 -7
- package/dist/tool.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/authentication.md +29 -5
- package/docs/billing.md +6 -0
- package/docs/concepts/agent-tools.md +11 -0
- package/docs/concepts/composition.md +3 -3
- package/docs/defaults.md +1 -0
- package/docs/errors.md +64 -4
- package/docs/events.md +84 -49
- package/docs/limits-and-quotas.md +24 -0
- package/docs/mcp.md +3 -2
- package/docs/networking.md +7 -1
- package/docs/outputs.md +36 -7
- package/docs/provider-runtime-capabilities.md +1 -1
- package/docs/quickstart.md +17 -7
- package/docs/run-config.md +3 -3
- package/docs/secrets.md +14 -0
- package/docs/skills.md +74 -44
- package/docs/vision-skills.md +3 -3
- package/examples/feature-tour.ts +4 -6
- package/examples/spike-settle-latency.ts +125 -0
- package/package.json +4 -3
- package/dist/_contracts/event-guards.d.ts +0 -67
- package/dist/_contracts/event-guards.js +0 -36
- package/dist/skill-tool.d.ts +0 -102
- package/dist/skill-tool.js +0 -190
- package/dist/skill-tool.js.map +0 -1
package/dist/skill.js
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { SKILL_NAME_PATTERN, SKILL_RESERVED_NAMES } from "./_contracts/index.js";
|
|
2
|
+
import { bundleSkillFiles, hashSkillBundle } from "./bundle.js";
|
|
3
|
+
import { fetchSkillArchive } from "./fetch-archive.js";
|
|
4
|
+
import { readDirectoryWithFidelity } from "./node-fs.js";
|
|
5
|
+
import { unzipSync } from "fflate";
|
|
6
|
+
/**
|
|
7
|
+
* A Skill is a FIRST-CLASS, workspace-scoped, by-name bundle of instructional /
|
|
8
|
+
* executable content (`SKILL.md` at the bundle root plus any supporting files).
|
|
9
|
+
* It is DISTINCT from a {@link Tool}: skills are passed on the session's separate
|
|
10
|
+
* `skills:` input, not `tools:`, and a run gets a single `skills` meta-tool
|
|
11
|
+
* (list/load) rather than one load-tool per skill.
|
|
12
|
+
*
|
|
13
|
+
* Lifecycle mirrors `Secret` promotion, but keyed to a workspace name:
|
|
14
|
+
* - The `Skill.from*` factories read a bundle, lift `name` + `description` from
|
|
15
|
+
* the `SKILL.md` YAML frontmatter (an explicit `{ name }` overrides), and
|
|
16
|
+
* canonically zip + hash the bytes → a DRAFT skill.
|
|
17
|
+
* - `skill.upload(client)` UPSERTS the workspace skill by name: it stages the
|
|
18
|
+
* bytes to the content-addressed asset store (presign/finalize) and PUTs the
|
|
19
|
+
* registry entry. Identical bytes are a no-op. Returns an uploaded `Skill`
|
|
20
|
+
* whose wire ref is `{ kind:"skill", name }` (BY NAME — no assetId, no hash).
|
|
21
|
+
* - Passing a DRAFT skill in `skills:` auto-upserts it on submit (same
|
|
22
|
+
* ergonomic as a draft `Tool` / `File`).
|
|
23
|
+
*
|
|
24
|
+
* Binding is by name and mutable: a re-upload under the same name changes what
|
|
25
|
+
* every future run referencing that name sees.
|
|
26
|
+
*/
|
|
27
|
+
export class Skill {
|
|
28
|
+
#ref;
|
|
29
|
+
#description;
|
|
30
|
+
#bundleBytes;
|
|
31
|
+
/** Set once this instance has upserted its bytes, so reuse skips the round-trip. */
|
|
32
|
+
#uploadedName;
|
|
33
|
+
/** Internal constructor. Use the `Skill.from*` factories. */
|
|
34
|
+
constructor(ref, description, bundleBytes) {
|
|
35
|
+
this.#ref = ref;
|
|
36
|
+
this.#description = description;
|
|
37
|
+
this.#bundleBytes = bundleBytes;
|
|
38
|
+
if (ref.kind === "skill") {
|
|
39
|
+
this.#uploadedName = ref.name;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** The wire ref: `{ kind:"skill", name }` once uploaded, or the draft shape before. */
|
|
43
|
+
get ref() {
|
|
44
|
+
return this.#ref;
|
|
45
|
+
}
|
|
46
|
+
/** True for a local-bytes skill that has not been upserted to the workspace yet. */
|
|
47
|
+
get isDraft() {
|
|
48
|
+
return this.#ref.kind === "draft";
|
|
49
|
+
}
|
|
50
|
+
get name() {
|
|
51
|
+
return this.#ref.name;
|
|
52
|
+
}
|
|
53
|
+
get description() {
|
|
54
|
+
return this.#description;
|
|
55
|
+
}
|
|
56
|
+
/** Internal: the workspace name this instance already upserted, or undefined. */
|
|
57
|
+
get _cachedName() {
|
|
58
|
+
return this.#uploadedName;
|
|
59
|
+
}
|
|
60
|
+
/** Internal: remember that this instance's bytes were upserted under `name`. */
|
|
61
|
+
_rememberUpload(name) {
|
|
62
|
+
this.#uploadedName = name;
|
|
63
|
+
}
|
|
64
|
+
// --- factories (source symmetry with File / AgentsMd / Tool) --------------
|
|
65
|
+
/**
|
|
66
|
+
* Read a local skill directory. It must contain `SKILL.md` at its root, whose
|
|
67
|
+
* YAML frontmatter supplies `description` and (unless `args.name` is given)
|
|
68
|
+
* `name`. When neither an explicit name nor a frontmatter name is present, the
|
|
69
|
+
* slugified directory basename is used.
|
|
70
|
+
*
|
|
71
|
+
* The directory is walked with FIDELITY (the same walk `File.fromPath` uses):
|
|
72
|
+
* `.aexignore` + the always-on defaults (`.git/`, `node_modules/`, …) prune the
|
|
73
|
+
* upload — so a skill dir carrying `node_modules` no longer ships it — and
|
|
74
|
+
* executable bits + symlinks are captured into a `.aexmeta.json` sidecar
|
|
75
|
+
* (emitted only when such metadata exists, so a pure-content skill dir stays
|
|
76
|
+
* byte-identical → dedup continuity). Bun/Node filesystem runtimes only.
|
|
77
|
+
*/
|
|
78
|
+
static async fromDir(rootDir, args = {}) {
|
|
79
|
+
const { files, meta } = await readDirectoryWithFidelity(rootDir, args.ignore);
|
|
80
|
+
return Skill.#fromFiles("Skill.fromDir", files, args.name, dirBasename(rootDir), meta);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Fetch a zip-archived skill from a URL. The archive is downloaded in the SDK
|
|
84
|
+
* process (caller-controlled URL — no SSRF surface), optionally integrity-checked
|
|
85
|
+
* against `sha256`, and reduced to the same files map as `Skill.fromDir` (a
|
|
86
|
+
* single wrapping top-level folder is stripped). It must expose `SKILL.md` at
|
|
87
|
+
* the root. The signed URL only needs to be valid for this call.
|
|
88
|
+
*/
|
|
89
|
+
static async fromUrl(url, args = {}) {
|
|
90
|
+
const files = await fetchSkillArchive(url, {
|
|
91
|
+
...(args.sha256 !== undefined ? { sha256: args.sha256 } : {}),
|
|
92
|
+
...(args.timeoutMs !== undefined ? { timeoutMs: args.timeoutMs } : {}),
|
|
93
|
+
...(args.fetch !== undefined ? { fetch: args.fetch } : {})
|
|
94
|
+
});
|
|
95
|
+
// A URL has no reliable directory basename, so no slug fallback.
|
|
96
|
+
return Skill.#fromFiles("Skill.fromUrl", files, args.name, undefined);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Build a draft skill from an in-memory files map (path -> string | bytes).
|
|
100
|
+
* Requires a root `SKILL.md`. Universal (no filesystem access). An optional
|
|
101
|
+
* `meta` (exec bits + symlinks) is threaded to the bundler for callers that
|
|
102
|
+
* carry fidelity metadata alongside a hand-built map; omit it and a plain map
|
|
103
|
+
* stays byte-identical to the pre-fidelity output.
|
|
104
|
+
*/
|
|
105
|
+
static async fromFiles(args) {
|
|
106
|
+
if (!args || typeof args !== "object" || args.files === undefined) {
|
|
107
|
+
throw new Error("Skill.fromFiles: { files } is required");
|
|
108
|
+
}
|
|
109
|
+
return Skill.#fromFiles("Skill.fromFiles", args.files, args.name, undefined, args.meta);
|
|
110
|
+
}
|
|
111
|
+
/** Convenience: build a single-file skill from a `SKILL.md` string. */
|
|
112
|
+
static async fromContent(skillMd, args = {}) {
|
|
113
|
+
if (typeof skillMd !== "string" || skillMd.length === 0) {
|
|
114
|
+
throw new Error("Skill.fromContent: skillMd must be a non-empty string");
|
|
115
|
+
}
|
|
116
|
+
return Skill.#fromFiles("Skill.fromContent", { "SKILL.md": skillMd }, args.name, undefined);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Build a draft skill from an already-zipped bundle. The zip is unpacked to a
|
|
120
|
+
* files map (directory entries dropped), then re-canonicalised so a
|
|
121
|
+
* `fromBytes` skill and the identical `fromDir` / `fromFiles` skill dedup by
|
|
122
|
+
* content hash. Requires `SKILL.md` at the archive root.
|
|
123
|
+
*/
|
|
124
|
+
static async fromBytes(args) {
|
|
125
|
+
if (!args || !(args.zip instanceof Uint8Array) || args.zip.byteLength === 0) {
|
|
126
|
+
throw new Error("Skill.fromBytes: { zip } must be a non-empty Uint8Array");
|
|
127
|
+
}
|
|
128
|
+
let entries;
|
|
129
|
+
try {
|
|
130
|
+
entries = unzipSync(args.zip);
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
throw new Error(`Skill.fromBytes: could not unzip the bundle (expected a .zip): ${err.message}`);
|
|
134
|
+
}
|
|
135
|
+
const files = {};
|
|
136
|
+
for (const [rawPath, bytes] of Object.entries(entries)) {
|
|
137
|
+
const path = rawPath.replace(/\\/g, "/");
|
|
138
|
+
if (path.endsWith("/"))
|
|
139
|
+
continue; // directory entry
|
|
140
|
+
files[path] = bytes;
|
|
141
|
+
}
|
|
142
|
+
return Skill.#fromFiles("Skill.fromBytes", files, args.name, undefined);
|
|
143
|
+
}
|
|
144
|
+
// --- workspace upsert -----------------------------------------------------
|
|
145
|
+
/**
|
|
146
|
+
* UPSERT this skill into the workspace registry by name and return an uploaded
|
|
147
|
+
* `Skill` whose ref is `{ kind:"skill", name }`. Two steps: stage the bytes to
|
|
148
|
+
* the content-addressed asset store (dedup makes identical bytes a no-op PUT),
|
|
149
|
+
* then PUT the registry entry (identical `contentHash` ⇒ server no-op). Reusing
|
|
150
|
+
* the SAME instance across submits skips both round-trips.
|
|
151
|
+
*
|
|
152
|
+
* Throws on an already-uploaded (non-draft) skill, mirroring `Tool.upload`.
|
|
153
|
+
*/
|
|
154
|
+
async upload(client) {
|
|
155
|
+
const bundle = this._takeDraftBundle();
|
|
156
|
+
if (!bundle) {
|
|
157
|
+
throw new Error("Skill.upload: only draft skills can be uploaded. This skill is already a workspace ref " +
|
|
158
|
+
"({ kind:'skill', name }); reference it by name in skills:[...].");
|
|
159
|
+
}
|
|
160
|
+
if (this.#uploadedName === undefined) {
|
|
161
|
+
await client._uploadAsset({
|
|
162
|
+
bytes: bundle.bytes,
|
|
163
|
+
hash: bundle.contentHash,
|
|
164
|
+
contentType: "application/zip"
|
|
165
|
+
});
|
|
166
|
+
await client._upsertSkill({
|
|
167
|
+
name: bundle.name,
|
|
168
|
+
contentHash: bundle.contentHash,
|
|
169
|
+
description: bundle.description,
|
|
170
|
+
sizeBytes: bundle.bytes.byteLength
|
|
171
|
+
});
|
|
172
|
+
this.#uploadedName = bundle.name;
|
|
173
|
+
}
|
|
174
|
+
return new Skill({ kind: "skill", name: bundle.name }, bundle.description);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Internal: yield the draft's bytes + metadata so `client.run` / `openSession`
|
|
178
|
+
* can auto-upsert it. Non-consuming: a Skill is reusable across sessions — the
|
|
179
|
+
* first use caches the resolved name so later uses skip the round-trip. Returns
|
|
180
|
+
* undefined for an already-uploaded skill.
|
|
181
|
+
*/
|
|
182
|
+
_takeDraftBundle() {
|
|
183
|
+
if (this.#ref.kind !== "draft" || !this.#bundleBytes) {
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
name: this.#ref.name,
|
|
188
|
+
description: this.#ref.description,
|
|
189
|
+
contentHash: this.#ref.contentHash,
|
|
190
|
+
bytes: this.#bundleBytes
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
toJSON() {
|
|
194
|
+
if (this.#ref.kind === "draft") {
|
|
195
|
+
throw new Error("Skill: a draft skill cannot be JSON-serialised — it only becomes a by-name wire ref once " +
|
|
196
|
+
"skill.upload(client) upserts it (or run / openSession auto-upserts it from skills:[...]).");
|
|
197
|
+
}
|
|
198
|
+
return this.#ref;
|
|
199
|
+
}
|
|
200
|
+
static async #fromFiles(source, files, explicitName, dirBasename, meta) {
|
|
201
|
+
const front = extractSkillFrontmatter(source, files);
|
|
202
|
+
const name = deriveSkillName(source, front.name, explicitName, dirBasename);
|
|
203
|
+
const description = front.description;
|
|
204
|
+
if (typeof description !== "string" || description.trim().length === 0) {
|
|
205
|
+
throw new Error(`${source}: a skill description is required — add a \`description:\` field to the SKILL.md YAML frontmatter`);
|
|
206
|
+
}
|
|
207
|
+
if (description.length > 2048) {
|
|
208
|
+
throw new Error(`${source}: description must be <= 2048 chars`);
|
|
209
|
+
}
|
|
210
|
+
const bundled = bundleSkillFiles(files, meta);
|
|
211
|
+
const contentHash = await hashSkillBundle(bundled.zip);
|
|
212
|
+
const ref = { kind: "draft", name, description, contentHash };
|
|
213
|
+
return new Skill(ref, description, bundled.zip);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Resolve a skill name: `{ name }` arg → SKILL.md frontmatter `name:` →
|
|
218
|
+
* (fromDir only) slugified directory basename; else error. Then validate the
|
|
219
|
+
* pattern, reject the `__` MCP separator, and reject reserved names. Never
|
|
220
|
+
* returns an invalid name silently — an underivable / non-conforming name throws.
|
|
221
|
+
*/
|
|
222
|
+
function deriveSkillName(source, frontmatterName, explicitName, dirBasename) {
|
|
223
|
+
let name = explicitName ?? frontmatterName;
|
|
224
|
+
if (name === undefined && dirBasename !== undefined) {
|
|
225
|
+
const slug = slugifyName(dirBasename);
|
|
226
|
+
if (slug.length > 0) {
|
|
227
|
+
name = slug;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
231
|
+
throw new Error(`${source}: a skill name is required — pass { name }, add a \`name:\` field to the SKILL.md ` +
|
|
232
|
+
`YAML frontmatter, or (for fromDir) use a directory whose basename slugifies to a valid name`);
|
|
233
|
+
}
|
|
234
|
+
if (!SKILL_NAME_PATTERN.test(name)) {
|
|
235
|
+
throw new Error(`${source}: name ${JSON.stringify(name)} must match ${SKILL_NAME_PATTERN.source}`);
|
|
236
|
+
}
|
|
237
|
+
if (name.includes("__")) {
|
|
238
|
+
throw new Error(`${source}: name must not contain "__"; that separator is reserved for MCP tools`);
|
|
239
|
+
}
|
|
240
|
+
if (SKILL_RESERVED_NAMES.has(name)) {
|
|
241
|
+
throw new Error(`${source}: name ${JSON.stringify(name)} is reserved (${[...SKILL_RESERVED_NAMES].join(", ")}); pick another`);
|
|
242
|
+
}
|
|
243
|
+
return name;
|
|
244
|
+
}
|
|
245
|
+
/** Lowercase, collapse non-`[a-z0-9]` runs to `-`, trim leading/trailing `-`. */
|
|
246
|
+
function slugifyName(input) {
|
|
247
|
+
return input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
248
|
+
}
|
|
249
|
+
/** Directory basename of a filesystem path (handles `/` and `\`, trailing slashes). */
|
|
250
|
+
function dirBasename(path) {
|
|
251
|
+
const normalised = path.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
252
|
+
return normalised.split("/").at(-1) ?? "";
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Read `SKILL.md` from a bundle files map and parse its YAML frontmatter for
|
|
256
|
+
* `name` + `description`. Throws when the bundle has no root `SKILL.md` (that is
|
|
257
|
+
* what makes a bundle a skill).
|
|
258
|
+
*/
|
|
259
|
+
function extractSkillFrontmatter(source, files) {
|
|
260
|
+
const raw = files["SKILL.md"];
|
|
261
|
+
if (raw === undefined) {
|
|
262
|
+
throw new Error(`${source}: the skill bundle must contain a SKILL.md at its root`);
|
|
263
|
+
}
|
|
264
|
+
const text = typeof raw === "string" ? raw : new TextDecoder().decode(raw);
|
|
265
|
+
return parseSkillFrontmatter(text);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Minimal YAML-frontmatter reader: pulls the `name` and `description` scalar
|
|
269
|
+
* values out of the leading `--- … ---` block. Only simple single-line
|
|
270
|
+
* `key: value` entries are supported (surrounding single/double quotes are
|
|
271
|
+
* stripped); anything else is ignored.
|
|
272
|
+
*/
|
|
273
|
+
function parseSkillFrontmatter(text) {
|
|
274
|
+
const src = text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
|
|
275
|
+
const match = /^---[ \t]*\r?\n([\s\S]*?)\r?\n---[ \t]*(?:\r?\n|$)/.exec(src);
|
|
276
|
+
if (!match) {
|
|
277
|
+
return {};
|
|
278
|
+
}
|
|
279
|
+
const out = {};
|
|
280
|
+
for (const line of match[1].split(/\r?\n/)) {
|
|
281
|
+
const kv = /^([A-Za-z0-9_-]+)[ \t]*:[ \t]*(.*)$/.exec(line);
|
|
282
|
+
if (!kv)
|
|
283
|
+
continue;
|
|
284
|
+
const key = kv[1].toLowerCase();
|
|
285
|
+
if (key !== "name" && key !== "description")
|
|
286
|
+
continue;
|
|
287
|
+
let value = kv[2].trim();
|
|
288
|
+
if (value.length >= 2 &&
|
|
289
|
+
((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'")))) {
|
|
290
|
+
value = value.slice(1, -1);
|
|
291
|
+
}
|
|
292
|
+
if (value.length > 0) {
|
|
293
|
+
out[key] = value;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return out;
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=skill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill.js","sourceRoot":"","sources":["../src/skill.ts"],"names":[],"mappings":"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"}
|
package/dist/tool.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ToolInputSchema, type ToolRef } from "./_contracts/index.js";
|
|
2
|
-
import { type SkillFiles } from "./bundle.js";
|
|
2
|
+
import { type BundleMeta, type SkillFiles } from "./bundle.js";
|
|
3
|
+
import type { IgnoreOptions } from "./node-walk.js";
|
|
3
4
|
export interface ToolManifestInput {
|
|
4
5
|
readonly name: string;
|
|
5
6
|
readonly description: string;
|
|
@@ -18,8 +19,19 @@ export declare class Tool {
|
|
|
18
19
|
_rememberAsset(assetId: string): void;
|
|
19
20
|
static fromFiles(args: ToolManifestInput & {
|
|
20
21
|
readonly files: SkillFiles;
|
|
22
|
+
readonly meta?: BundleMeta;
|
|
23
|
+
}): Promise<Tool>;
|
|
24
|
+
/**
|
|
25
|
+
* Read a local tool bundle directory (`tool.json` at its root + support files).
|
|
26
|
+
* The directory is walked with FIDELITY (the same walk `File.fromPath` uses):
|
|
27
|
+
* `.aexignore` + the always-on defaults (`.git/`, `node_modules/`, …) prune the
|
|
28
|
+
* upload, and executable bits + symlinks are captured into a `.aexmeta.json`
|
|
29
|
+
* sidecar (emitted only when such metadata exists, so a pure-content tool dir
|
|
30
|
+
* stays byte-identical → dedup continuity). Bun/Node filesystem runtimes only.
|
|
31
|
+
*/
|
|
32
|
+
static fromPath(rootDir: string, args?: {
|
|
33
|
+
readonly ignore?: IgnoreOptions;
|
|
21
34
|
}): Promise<Tool>;
|
|
22
|
-
static fromPath(rootDir: string): Promise<Tool>;
|
|
23
35
|
static fromAsset(ref: ToolRef): Tool;
|
|
24
36
|
_takeDraftBundle(): {
|
|
25
37
|
ref: ToolRef;
|
package/dist/tool.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TOOL_NAME_PATTERN, normaliseSkillBundlePath } from "./_contracts/index.js";
|
|
2
2
|
import { bundleToolFiles, hashSkillBundle } from "./bundle.js";
|
|
3
|
-
import {
|
|
3
|
+
import { readDirectoryWithFidelity } from "./node-fs.js";
|
|
4
4
|
export class Tool {
|
|
5
5
|
#ref;
|
|
6
6
|
#inlineBytes;
|
|
@@ -28,8 +28,8 @@ export class Tool {
|
|
|
28
28
|
if (!args || typeof args !== "object") {
|
|
29
29
|
throw new Error("Tool.fromFiles: args is required");
|
|
30
30
|
}
|
|
31
|
-
const manifest = normalizeToolManifest("Tool.fromFiles", args);
|
|
32
|
-
const bundled = bundleToolFiles(args.files, manifest);
|
|
31
|
+
const manifest = normalizeToolManifest("Tool.fromFiles", args, args.files);
|
|
32
|
+
const bundled = bundleToolFiles(args.files, manifest, args.meta);
|
|
33
33
|
const contentHash = await hashSkillBundle(bundled.zip);
|
|
34
34
|
const ref = {
|
|
35
35
|
kind: "draft",
|
|
@@ -39,8 +39,16 @@ export class Tool {
|
|
|
39
39
|
};
|
|
40
40
|
return new Tool(ref, bundled.zip);
|
|
41
41
|
}
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Read a local tool bundle directory (`tool.json` at its root + support files).
|
|
44
|
+
* The directory is walked with FIDELITY (the same walk `File.fromPath` uses):
|
|
45
|
+
* `.aexignore` + the always-on defaults (`.git/`, `node_modules/`, …) prune the
|
|
46
|
+
* upload, and executable bits + symlinks are captured into a `.aexmeta.json`
|
|
47
|
+
* sidecar (emitted only when such metadata exists, so a pure-content tool dir
|
|
48
|
+
* stays byte-identical → dedup continuity). Bun/Node filesystem runtimes only.
|
|
49
|
+
*/
|
|
50
|
+
static async fromPath(rootDir, args) {
|
|
51
|
+
const { files, meta } = await readDirectoryWithFidelity(rootDir, args?.ignore);
|
|
44
52
|
const rawManifest = files["tool.json"];
|
|
45
53
|
if (rawManifest === undefined) {
|
|
46
54
|
throw new Error('Tool.fromPath: tool.json is required at the tool bundle root');
|
|
@@ -59,7 +67,8 @@ export class Tool {
|
|
|
59
67
|
const { ["tool.json"]: _manifest, ...bundleFiles } = files;
|
|
60
68
|
return Tool.fromFiles({
|
|
61
69
|
...parsed,
|
|
62
|
-
files: bundleFiles
|
|
70
|
+
files: bundleFiles,
|
|
71
|
+
meta
|
|
63
72
|
});
|
|
64
73
|
}
|
|
65
74
|
static fromAsset(ref) {
|
|
@@ -95,7 +104,7 @@ export class Tool {
|
|
|
95
104
|
return this.#ref;
|
|
96
105
|
}
|
|
97
106
|
}
|
|
98
|
-
function normalizeToolManifest(source, input) {
|
|
107
|
+
function normalizeToolManifest(source, input, files) {
|
|
99
108
|
const name = input.name;
|
|
100
109
|
if (typeof name !== "string" || !TOOL_NAME_PATTERN.test(name)) {
|
|
101
110
|
throw new Error(`${source}: name must match ${TOOL_NAME_PATTERN.source}`);
|
|
@@ -115,6 +124,7 @@ function normalizeToolManifest(source, input) {
|
|
|
115
124
|
throw new Error(`${source}: inputSchema.type must be "object"`);
|
|
116
125
|
}
|
|
117
126
|
const entry = normaliseSkillBundlePath(input.entry);
|
|
127
|
+
assertJsModuleEntry(source, entry, input.entry, files);
|
|
118
128
|
return {
|
|
119
129
|
name,
|
|
120
130
|
description,
|
|
@@ -122,6 +132,22 @@ function normalizeToolManifest(source, input) {
|
|
|
122
132
|
entry
|
|
123
133
|
};
|
|
124
134
|
}
|
|
135
|
+
const JS_MODULE_ENTRY = /\.(?:js|mjs|cjs)$/i;
|
|
136
|
+
/**
|
|
137
|
+
* Validate the tool's ENTRY is a JS module at authoring time (fail-fast), not
|
|
138
|
+
* mid-run when the runtime module-loader rejects a `run.sh`. The entry must end
|
|
139
|
+
* in `.js`/`.mjs`/`.cjs` and — when the bundle files are known
|
|
140
|
+
* ({@link Tool.fromFiles}) — must be present in `files`.
|
|
141
|
+
*/
|
|
142
|
+
function assertJsModuleEntry(source, entry, rawEntry, files) {
|
|
143
|
+
const basename = entry.split("/").pop() ?? entry;
|
|
144
|
+
if (!JS_MODULE_ENTRY.test(basename)) {
|
|
145
|
+
throw new Error(`${source}: entry must be a JS module (.js/.mjs/.cjs) that default-exports a function or { execute }; got ${JSON.stringify(rawEntry)}`);
|
|
146
|
+
}
|
|
147
|
+
if (files !== undefined && !(entry in files) && !(rawEntry in files)) {
|
|
148
|
+
throw new Error(`${source}: entry ${JSON.stringify(rawEntry)} is not present in files (keys: ${Object.keys(files).join(", ") || "(none)"})`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
125
151
|
function normalizeToolRef(source, ref) {
|
|
126
152
|
const manifest = normalizeToolManifest(source, {
|
|
127
153
|
name: ref.name,
|
package/dist/tool.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EAIzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,eAAe,EACf,eAAe,
|
|
1
|
+
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/docs/authentication.md
CHANGED
|
@@ -25,22 +25,46 @@ it once with `aex login`:
|
|
|
25
25
|
```ts
|
|
26
26
|
import { Aex } from "@aexhq/sdk";
|
|
27
27
|
|
|
28
|
-
const aex = new Aex(process.env.AEX_API_KEY!);
|
|
29
|
-
// also accepted: new Aex({ apiKey: ... }) and the alias new Aex({ apiKey: ... })
|
|
28
|
+
const aex = new Aex(process.env.AEX_API_KEY!);
|
|
30
29
|
```
|
|
31
30
|
|
|
32
31
|
```bash
|
|
33
|
-
aex whoami --api-key "$AEX_API_KEY"
|
|
32
|
+
npx aex whoami --api-key "$AEX_API_KEY"
|
|
34
33
|
|
|
35
34
|
# or persist it once, then omit --api-key on later commands:
|
|
36
|
-
aex login --api-key "$AEX_API_KEY"
|
|
37
|
-
aex whoami
|
|
35
|
+
npx aex login --api-key "$AEX_API_KEY"
|
|
36
|
+
npx aex whoami
|
|
38
37
|
```
|
|
39
38
|
|
|
39
|
+
(`new Aex(apiKey)` is the canonical constructor; the equivalent options form is
|
|
40
|
+
documented once in [Credentials](credentials.md).)
|
|
41
|
+
|
|
40
42
|
The token travels as a standard `Authorization: Bearer` header. Treat it like
|
|
41
43
|
any other secret: keep it in environment variables or a secret manager, never
|
|
42
44
|
in run config, prompts, or committed files.
|
|
43
45
|
|
|
46
|
+
## Plane routing and the `baseUrl` guard
|
|
47
|
+
|
|
48
|
+
An aex API key is **self-describing**: it embeds the plane (`dev` / `prd`) and
|
|
49
|
+
region it was minted for. The constructor parses the key and routes accordingly,
|
|
50
|
+
with **zero network**:
|
|
51
|
+
|
|
52
|
+
- **Omit `baseUrl`** and a `prd` key routes to the canonical hosted API plane
|
|
53
|
+
(`https://api.aex.dev`). A `dev` key has no stable public host yet, so a dev
|
|
54
|
+
key with no `baseUrl` throws `CredentialValidationError` asking you to pass one.
|
|
55
|
+
- **Supply a `baseUrl` whose plane disagrees with the key** (e.g. a `dev` key
|
|
56
|
+
pointed at `https://api.aex.dev`) and the constructor throws
|
|
57
|
+
`CredentialValidationError` **before any request** — you no longer discover the
|
|
58
|
+
mismatch as a late `401 token_invalid` after a full round-trip.
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
// prd key → routes to https://api.aex.dev automatically:
|
|
62
|
+
const prd = new Aex(process.env.AEX_PRD_KEY!);
|
|
63
|
+
|
|
64
|
+
// dev key → pass the dev plane's baseUrl explicitly:
|
|
65
|
+
const dev = new Aex(process.env.AEX_DEV_KEY!, { baseUrl: process.env.AEX_DEV_URL! });
|
|
66
|
+
```
|
|
67
|
+
|
|
44
68
|
## Scopes
|
|
45
69
|
|
|
46
70
|
A token carries a set of **scopes**; every API route requires one, and a token
|
package/docs/billing.md
CHANGED
|
@@ -8,6 +8,12 @@ Workspace-level billing, subscription, and webhook verification calls are
|
|
|
8
8
|
token-scoped like every other client call — the workspace is derived
|
|
9
9
|
server-side from the API key.
|
|
10
10
|
|
|
11
|
+
The billing reads — `aex.billing()`, `aex.billingLedger()`, and the CLI
|
|
12
|
+
`aex billing` (and its `ledger` sub-verb) — require the **`billing:read`**
|
|
13
|
+
scope; a token without it fails with `403 insufficient_scope` (see
|
|
14
|
+
[Errors](errors.md)). This is why the [Quickstart](quickstart.md) mints
|
|
15
|
+
`billing:read` alongside `runs:read` / `runs:write` / `outputs:read`.
|
|
16
|
+
|
|
11
17
|
## Read the billing summary
|
|
12
18
|
|
|
13
19
|
`aex.billing()` returns the workspace's prepaid balance, current-month spend,
|
|
@@ -10,6 +10,7 @@ Managed runs inject the complete builtin tool set into the agent by default:
|
|
|
10
10
|
- `read_file`, `write_file`, `edit_file` — file read/create/patch
|
|
11
11
|
- `grep`, `glob` — search file contents and paths
|
|
12
12
|
- `head`, `tail` — read bounded file slices
|
|
13
|
+
- `ls`, `stat`, `wc` — list a directory, inspect path metadata, count lines/words/bytes
|
|
13
14
|
- `web_fetch`, `web_search` — fetch a URL / managed web search
|
|
14
15
|
- `todo_write` — maintain a todo list
|
|
15
16
|
- `subagent`, `subagent_result` — delegate to and read back from child runs (see [Subagents](subagents.md))
|
|
@@ -32,6 +33,16 @@ to pick a narrow subset alongside `includeBuiltinTools: false`.
|
|
|
32
33
|
The final tool list is ordered: resolved builtin tools, then custom tools, then
|
|
33
34
|
MCP tools.
|
|
34
35
|
|
|
36
|
+
## Custom tools
|
|
37
|
+
|
|
38
|
+
Attach your own tool in `tools` as a bundle built with `Tool.fromFiles(...)` (an
|
|
39
|
+
explicit `{ entry, files }`) or `Tool.fromPath(dir)` (a directory with a
|
|
40
|
+
`tool.json` at its root). The bundle's **entry must be a JS module** — a
|
|
41
|
+
`.js`/`.mjs`/`.cjs` file present in the bundle that **default-exports a function
|
|
42
|
+
or an object with an `execute` method**. This is validated at authoring time, so
|
|
43
|
+
a non-JS entry (e.g. a `run.sh`) is rejected right where you build the tool, not
|
|
44
|
+
opaquely mid-run when the runtime's module loader would fail to import it.
|
|
45
|
+
|
|
35
46
|
Networking is open by default within the platform's managed egress ceiling and
|
|
36
47
|
a fixed SSRF deny-list. `web_fetch` and `web_search` reach the network over a
|
|
37
48
|
managed, SSRF-guarded path that is **not** governed by `environment.networking`,
|
|
@@ -10,7 +10,7 @@ runtime before the first agent turn.
|
|
|
10
10
|
|
|
11
11
|
| Need | Primitive |
|
|
12
12
|
| --- | --- |
|
|
13
|
-
|
|
|
13
|
+
| Instructional skill bundles | `Skill.fromDir`, `Skill.fromUrl`, `Skill.fromFiles` |
|
|
14
14
|
| Agent instructions | `AgentsMd.fromPath`, `AgentsMd.fromContent` |
|
|
15
15
|
| Reference files and folders | `File.fromPath`, `File.fromBytes` |
|
|
16
16
|
| Remote tools | `McpServer.remote`, `McpServer.fromId` |
|
|
@@ -18,14 +18,14 @@ runtime before the first agent turn.
|
|
|
18
18
|
| Runtime secrets for your code | `Secret.value`, `Secret.ref`, `environment.secrets` |
|
|
19
19
|
|
|
20
20
|
```ts
|
|
21
|
-
import { AgentsMd, File, McpServer, Models, Secret,
|
|
21
|
+
import { AgentsMd, File, McpServer, Models, Secret, Skill } from "@aexhq/sdk";
|
|
22
22
|
|
|
23
23
|
await aex.run({
|
|
24
24
|
model: Models.CLAUDE_HAIKU_4_5,
|
|
25
25
|
message: "Use the attached docs and tools to produce a report.",
|
|
26
26
|
agentsMd: [await AgentsMd.fromContent("Follow the repo conventions.", { name: "repo-rules" })],
|
|
27
27
|
files: [await File.fromPath("./input")],
|
|
28
|
-
|
|
28
|
+
skills: [await Skill.fromDir("./skills/report-writer", { name: "report-writer" })],
|
|
29
29
|
mcpServers: [McpServer.remote({ name: "github", url: "https://example.com/mcp" })],
|
|
30
30
|
environment: {
|
|
31
31
|
secrets: { INTERNAL_API_TOKEN: Secret.value(process.env.INTERNAL_API_TOKEN!) },
|
package/docs/defaults.md
CHANGED
|
@@ -23,6 +23,7 @@ For the hard ceilings and who can raise them, see
|
|
|
23
23
|
| `timeout` (run deadline) | 8 hours (also the ceiling) | Per-session via `overrides.timeout` (e.g. `"30m"`, `"2h"`). Values outside the run-timeout floor (1 minute) / ceiling (8 hours) are rejected with `RunConfigValidationError` before submission. | `RUN_DEFAULT_TIMEOUT_MS` |
|
|
24
24
|
| `runtime` (machine size) | `shared-0.25x-1gb` — 0.25 vCPU, 1 GB | Per-session via `runtime` (use `Sizes.*` in TypeScript). | `RUN_DEFAULT_RUNTIME_SIZE` |
|
|
25
25
|
| `overrides.maxSpendUsd` (per-session spend cap) | None — no spend cap (the session is still bounded by its `timeout` and any workspace-level cap) | Per-session via `overrides.maxSpendUsd` (a positive USD amount); the session is stopped once its spend would exceed the cap. | — |
|
|
26
|
+
| `overrides.maxTurns` (agent iterations per run) | 20 (ceiling 200) | Per-session via `overrides.maxTurns` (a positive integer, clamped to the ceiling). | `RUN_DEFAULT_MAX_TURNS` |
|
|
26
27
|
|
|
27
28
|
## Tools
|
|
28
29
|
|