antpath 0.10.14 → 0.11.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/LICENSE +201 -0
- package/README.md +16 -8
- package/dist/_shared/blueprint.d.ts +93 -108
- package/dist/_shared/blueprint.js +144 -78
- package/dist/_shared/cleanup-policy.d.ts +2 -2
- package/dist/_shared/cleanup-policy.js +2 -5
- package/dist/_shared/http.d.ts +2 -2
- package/dist/_shared/index.d.ts +7 -1
- package/dist/_shared/index.js +6 -1
- package/dist/_shared/mcp-proxy-url.d.ts +55 -0
- package/dist/_shared/mcp-proxy-url.js +65 -0
- package/dist/_shared/operations.d.ts +55 -8
- package/dist/_shared/operations.js +163 -20
- package/dist/_shared/provider-proxy-url.d.ts +64 -0
- package/dist/_shared/provider-proxy-url.js +73 -0
- package/dist/_shared/proxy-validation.d.ts +1 -1
- package/dist/_shared/proxy-validation.js +2 -2
- package/dist/_shared/run-unit.d.ts +23 -36
- package/dist/_shared/run-unit.js +30 -46
- package/dist/_shared/runner-event.d.ts +120 -0
- package/dist/_shared/runner-event.js +193 -0
- package/dist/_shared/runner-job.d.ts +159 -0
- package/dist/_shared/runner-job.js +54 -0
- package/dist/_shared/runtime-manifest.d.ts +191 -0
- package/dist/_shared/runtime-manifest.js +221 -0
- package/dist/_shared/runtime-types.d.ts +7 -16
- package/dist/_shared/sse.d.ts +74 -0
- package/dist/_shared/sse.js +0 -0
- package/dist/_shared/stable.d.ts +15 -10
- package/dist/_shared/stable.js +15 -10
- package/dist/_shared/submission.d.ts +199 -73
- package/dist/_shared/submission.js +409 -210
- package/dist/_shared/telemetry.d.ts +2 -2
- package/dist/_shared/telemetry.js +2 -2
- package/dist/_shared/template/index.d.ts +0 -1
- package/dist/_shared/template/index.js +0 -1
- package/dist/agents-md.d.ts +25 -67
- package/dist/agents-md.js +35 -121
- package/dist/agents-md.js.map +1 -1
- package/dist/asset-upload.d.ts +34 -0
- package/dist/asset-upload.js +34 -0
- package/dist/asset-upload.js.map +1 -1
- package/dist/blueprint.d.ts +3 -3
- package/dist/bundle.d.ts +2 -2
- package/dist/bundle.js +1 -1
- package/dist/cli.mjs +559 -105
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/client.d.ts +53 -22
- package/dist/client.js +196 -130
- package/dist/client.js.map +1 -1
- package/dist/file.d.ts +28 -94
- package/dist/file.js +35 -175
- package/dist/file.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.d.ts +10 -2
- package/dist/mcp-server.js +17 -2
- package/dist/mcp-server.js.map +1 -1
- package/dist/skill.d.ts +44 -214
- package/dist/skill.js +50 -284
- package/dist/skill.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/docs/cleanup.md +1 -1
- package/docs/credentials.md +2 -2
- package/docs/events.md +8 -8
- package/docs/outputs.md +2 -0
- package/docs/quickstart.md +18 -2
- package/docs/skills.md +1 -3
- package/docs/templates.md +6 -5
- package/package.json +2 -1
- package/dist/_shared/secrets.d.ts +0 -7
- package/dist/_shared/secrets.js +0 -20
- package/dist/_shared/template/mapper.d.ts +0 -11
- package/dist/_shared/template/mapper.js +0 -70
package/dist/skill.js
CHANGED
|
@@ -1,110 +1,58 @@
|
|
|
1
1
|
import { SKILL_NAME_PATTERN } from "./_shared/index.js";
|
|
2
2
|
import { bundleSkillFiles, hashSkillBundle } from "./bundle.js";
|
|
3
3
|
import { readDirectoryAsFiles } from "./node-fs.js";
|
|
4
|
-
import { chooseUploadStrategy, uploadChunked } from "./asset-upload.js";
|
|
5
4
|
/**
|
|
6
|
-
* One `Skill` class,
|
|
7
|
-
*
|
|
8
|
-
* - **Workspace** — uploaded to the antpath platform and reused across
|
|
9
|
-
* runs.
|
|
10
|
-
* ```ts
|
|
11
|
-
* const persisted = await Skill.fromFiles({ name, files }).upload(client);
|
|
12
|
-
* // or
|
|
13
|
-
* const ref = Skill.fromId("skl_abc123");
|
|
14
|
-
* ```
|
|
5
|
+
* One `Skill` class, two usage modes:
|
|
15
6
|
*
|
|
16
7
|
* - **Provider built-in** — references a provider-side skill (e.g.
|
|
17
8
|
* Anthropic's `pdf` / `xlsx` / `docx` / `pptx` prebuilt Agent
|
|
18
|
-
* Skills). Not uploaded
|
|
9
|
+
* Skills). Not uploaded.
|
|
19
10
|
* ```ts
|
|
20
11
|
* const pdf = Skill.provider({ vendor: "anthropic", skillId: "pdf" });
|
|
21
12
|
* ```
|
|
22
|
-
* Note: Anthropic web search is a Messages-API *tool*
|
|
23
|
-
* (`{ type: "web_search_…" }`), not an Agent Skill — `Skill.provider`
|
|
24
|
-
* does not enable it.
|
|
25
13
|
*
|
|
26
|
-
* - **
|
|
27
|
-
*
|
|
28
|
-
*
|
|
14
|
+
* - **Local bytes** — built from local files. `client.submitRun`
|
|
15
|
+
* materializes the bytes to R2 (content-addressable, workspace-
|
|
16
|
+
* scoped) before the run lands; the wire ref becomes `kind:"r2"`.
|
|
29
17
|
* ```ts
|
|
30
18
|
* const rules = await Skill.fromFiles({ name: "rules", files: {...} });
|
|
31
19
|
* await client.submitRun({ skills: [rules], ... });
|
|
32
20
|
* ```
|
|
33
21
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* 1. Passing it to `submitRun` uploads the bytes for that one run only
|
|
39
|
-
* and assigns a positional slot id (`transient-0`, `transient-1`, …).
|
|
40
|
-
* The same instance may be passed to multiple `submitRun` calls
|
|
41
|
-
* until it is consumed by `.upload(...)`.
|
|
42
|
-
*
|
|
43
|
-
* 2. Calling `await skill.upload(client)` persists the bundle to the
|
|
44
|
-
* workspace skill store and returns a **new** `Skill` instance
|
|
45
|
-
* whose `.ref.kind === "workspace"`. The **original** is marked
|
|
46
|
-
* **consumed**:
|
|
47
|
-
* - any further use in `submitRun` throws a clear validation error,
|
|
48
|
-
* - `.upload(...)` on the consumed instance throws,
|
|
49
|
-
* - `JSON.stringify` / `toJSON()` on the consumed instance throws.
|
|
50
|
-
*
|
|
51
|
-
* Use the returned (workspace) Skill from then on. The consumed
|
|
52
|
-
* reference exists only to surface the mistake loudly the first
|
|
53
|
-
* time the user re-uses it; it never silently re-uploads as
|
|
54
|
-
* transient.
|
|
55
|
-
*
|
|
56
|
-
* Unstaged transient Skills do NOT round-trip through JSON (the bytes
|
|
57
|
-
* cannot be serialised back). `toJSON()` throws in that state too —
|
|
58
|
-
* persist via `.upload(client)` first, or pass the unstaged Skill
|
|
59
|
-
* directly to `submitRun`.
|
|
60
|
-
*
|
|
61
|
-
* The Skill class is the only public way to build a transient bundle;
|
|
62
|
-
* the SDK never accepts a raw `TransientSkillRef` object from user code.
|
|
22
|
+
* The workspace pre-upload concept is gone — R2's content-addressable
|
|
23
|
+
* dedup at submit time makes the same bytes a no-op upload on subsequent
|
|
24
|
+
* runs. There is no `Skill.fromId(...)` and no `.upload(client)`.
|
|
63
25
|
*/
|
|
64
26
|
export class Skill {
|
|
65
|
-
/** Workspace skill record returned by the BFF (only set for workspace-uploaded skills). */
|
|
66
|
-
record;
|
|
67
27
|
#ref;
|
|
68
|
-
#
|
|
28
|
+
#inlineBytes;
|
|
69
29
|
#consumed = false;
|
|
70
30
|
/**
|
|
71
|
-
* Internal constructor. Use `Skill.
|
|
72
|
-
* `Skill.
|
|
31
|
+
* Internal constructor. Use `Skill.provider`, `Skill.fromFiles`, or
|
|
32
|
+
* `Skill.fromPath` to create instances.
|
|
73
33
|
*/
|
|
74
|
-
constructor(ref,
|
|
34
|
+
constructor(ref, inlineBytes) {
|
|
75
35
|
this.#ref = ref;
|
|
76
|
-
this
|
|
77
|
-
this.#transientBytes = transientBytes;
|
|
36
|
+
this.#inlineBytes = inlineBytes;
|
|
78
37
|
}
|
|
79
38
|
/**
|
|
80
|
-
* The wire-level reference.
|
|
81
|
-
*
|
|
82
|
-
* `
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* For consumed Skills, the getter still returns the original
|
|
86
|
-
* transient ref so error messages can be precise — but using a
|
|
87
|
-
* consumed Skill in any submit/serialise path throws.
|
|
39
|
+
* The wire-level reference. Returns the SDK-private draft shape for
|
|
40
|
+
* un-materialized skills (kind:"draft", with name + contentHash).
|
|
41
|
+
* `client.submitRun` walks these and uploads to R2 before the run
|
|
42
|
+
* lands.
|
|
88
43
|
*/
|
|
89
44
|
get ref() {
|
|
90
45
|
return this.#ref;
|
|
91
46
|
}
|
|
92
|
-
/**
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
static fromId(id) {
|
|
99
|
-
if (typeof id !== "string" || !id) {
|
|
100
|
-
throw new Error("Skill.fromId: id is required");
|
|
101
|
-
}
|
|
102
|
-
return new Skill({ kind: "workspace", id });
|
|
47
|
+
/** True for local-bytes Skills that haven't been uploaded yet. */
|
|
48
|
+
get isDraft() {
|
|
49
|
+
return this.#ref.kind === "draft" && !this.#consumed;
|
|
50
|
+
}
|
|
51
|
+
get isConsumed() {
|
|
52
|
+
return this.#consumed;
|
|
103
53
|
}
|
|
104
54
|
/**
|
|
105
|
-
* Reference a provider built-in skill.
|
|
106
|
-
* `skillId` and `version` mean; the SDK only forwards the values
|
|
107
|
-
* verbatim to the platform.
|
|
55
|
+
* Reference a provider built-in skill (e.g. Anthropic Skills).
|
|
108
56
|
*/
|
|
109
57
|
static provider(args) {
|
|
110
58
|
if (!args || typeof args !== "object") {
|
|
@@ -122,14 +70,11 @@ export class Skill {
|
|
|
122
70
|
return new Skill(ref);
|
|
123
71
|
}
|
|
124
72
|
/**
|
|
125
|
-
* Build
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* `sha256:<hex>` content hash
|
|
129
|
-
*
|
|
130
|
-
* The returned Skill carries the bytes privately. Pass it to
|
|
131
|
-
* `submitRun` for transient (per-run) use, or call `.upload(client)`
|
|
132
|
-
* to persist it as a workspace skill.
|
|
73
|
+
* Build a draft Skill from an inline files map. The SDK validates
|
|
74
|
+
* basic safety (no path traversal, size caps, has `SKILL.md`),
|
|
75
|
+
* deterministically zips the bundle, and computes the
|
|
76
|
+
* `sha256:<hex>` content hash. `client.submitRun` materializes
|
|
77
|
+
* these to R2 before the run lands.
|
|
133
78
|
*/
|
|
134
79
|
static async fromFiles(args) {
|
|
135
80
|
if (!args || typeof args !== "object") {
|
|
@@ -141,230 +86,51 @@ export class Skill {
|
|
|
141
86
|
const bundled = bundleSkillFiles(args.files);
|
|
142
87
|
const contentHash = await hashSkillBundle(bundled.zip);
|
|
143
88
|
const ref = {
|
|
144
|
-
kind: "
|
|
145
|
-
slot: UNSTAGED_SLOT,
|
|
89
|
+
kind: "draft",
|
|
146
90
|
name: args.name,
|
|
147
91
|
contentHash
|
|
148
92
|
};
|
|
149
|
-
return new Skill(ref,
|
|
93
|
+
return new Skill(ref, bundled.zip);
|
|
150
94
|
}
|
|
151
95
|
/**
|
|
152
|
-
* Read a local directory and build
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
* The returned Skill behaves identically to one built via
|
|
156
|
-
* `Skill.fromFiles` — pass it to `submitRun` for transient use, or
|
|
157
|
-
* call `.upload(client)` to persist as a workspace skill.
|
|
96
|
+
* Read a local directory and build a draft Skill. Symlinks and
|
|
97
|
+
* non-regular files are skipped. Node-only.
|
|
158
98
|
*/
|
|
159
99
|
static async fromPath(rootDir, args) {
|
|
160
100
|
const files = await readDirectoryAsFiles(rootDir);
|
|
161
101
|
return Skill.fromFiles({ name: args.name, files });
|
|
162
102
|
}
|
|
163
103
|
/**
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
* Only unstaged transient Skills can be uploaded. Calling this on a
|
|
171
|
-
* workspace-ref Skill, a provider-ref Skill, or a previously
|
|
172
|
-
* consumed Skill throws.
|
|
173
|
-
*
|
|
174
|
-
* Accepts either an `AntpathClient` (preferred) or its
|
|
175
|
-
* `SkillsClient` if the caller already has a handle to it.
|
|
176
|
-
*/
|
|
177
|
-
async upload(client) {
|
|
178
|
-
if (this.#consumed) {
|
|
179
|
-
throw new Error(consumedMessage());
|
|
180
|
-
}
|
|
181
|
-
if (this.#ref.kind !== "transient" || !this.#transientBytes) {
|
|
182
|
-
throw new Error("Skill.upload: only unstaged transient Skills (built via Skill.fromFiles / Skill.fromPath) can be uploaded; " +
|
|
183
|
-
"use Skill.fromId(record.id) to reference an already-persisted skill");
|
|
184
|
-
}
|
|
185
|
-
const bytes = this.#transientBytes;
|
|
186
|
-
const strategy = chooseUploadStrategy(bytes.byteLength);
|
|
187
|
-
if (strategy === "chunked") {
|
|
188
|
-
// Large bundle: three-step TUS upload.
|
|
189
|
-
const chunkedClient = resolveChunkedUploader(client);
|
|
190
|
-
if (!chunkedClient) {
|
|
191
|
-
throw new Error("Skill.upload: bundle exceeds 6 MiB but the client does not support chunked uploads. " +
|
|
192
|
-
"Pass an AntpathClient instance to enable chunked (TUS) upload.");
|
|
193
|
-
}
|
|
194
|
-
const { init, finalize } = chunkedClient;
|
|
195
|
-
const session = await init({
|
|
196
|
-
kind: "skill",
|
|
197
|
-
name: this.#ref.name,
|
|
198
|
-
sizeBytes: bytes.byteLength,
|
|
199
|
-
hash: this.#ref.contentHash
|
|
200
|
-
});
|
|
201
|
-
await uploadChunked({
|
|
202
|
-
bundle: bytes,
|
|
203
|
-
tusUrl: session.tusUrl,
|
|
204
|
-
tusToken: session.tusToken,
|
|
205
|
-
uploadHeaders: session.uploadHeaders,
|
|
206
|
-
hash: this.#ref.contentHash
|
|
207
|
-
});
|
|
208
|
-
await finalize({
|
|
209
|
-
assetId: session.assetId,
|
|
210
|
-
kind: "skill",
|
|
211
|
-
hash: this.#ref.contentHash,
|
|
212
|
-
storagePath: session.storagePath
|
|
213
|
-
});
|
|
214
|
-
this.#consumed = true;
|
|
215
|
-
return new Skill({ kind: "workspace", id: session.assetId });
|
|
216
|
-
}
|
|
217
|
-
// Small bundle: existing single-request multipart POST.
|
|
218
|
-
const uploader = resolveUploader(client);
|
|
219
|
-
const record = await uploader({ name: this.#ref.name, body: bytes });
|
|
220
|
-
// Only mark consumed AFTER a successful upload — a failed upload
|
|
221
|
-
// leaves the original instance reusable so the caller can retry.
|
|
222
|
-
this.#consumed = true;
|
|
223
|
-
return new Skill({ kind: "workspace", id: record.id }, record);
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Persist this unstaged transient Skill as a workspace skill **only
|
|
227
|
-
* if** an existing skill with the same `(name, contentHash)` is not
|
|
228
|
-
* already live.
|
|
104
|
+
* Internal: yield the draft's bytes + metadata so `client.submitRun`
|
|
105
|
+
* can upload to R2. After this returns, the Skill is marked consumed
|
|
106
|
+
* so a second submitRun call against the same instance throws
|
|
107
|
+
* (avoid silently re-uploading; explicit re-construction is the
|
|
108
|
+
* supported retry pattern).
|
|
229
109
|
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
* 1. Hash is already known from `Skill.fromFiles` / `fromPath`.
|
|
233
|
-
* 2. Call `client.skills.findByHash({ name, contentHash })`. If a
|
|
234
|
-
* live row exists, mark this instance consumed and return a
|
|
235
|
-
* new `Skill` backed by that record.
|
|
236
|
-
* 3. Otherwise call `upload(client)`.
|
|
237
|
-
*
|
|
238
|
-
* Returns either the existing or newly-created workspace Skill;
|
|
239
|
-
* callers do not need to branch.
|
|
240
|
-
*
|
|
241
|
-
* Only unstaged transient Skills can be `uploadIfChanged`. Calling
|
|
242
|
-
* this on a workspace-ref Skill, a provider-ref Skill, or a
|
|
243
|
-
* previously consumed Skill throws.
|
|
110
|
+
* Returns undefined for non-draft (provider / already-materialized)
|
|
111
|
+
* Skills.
|
|
244
112
|
*/
|
|
245
|
-
|
|
113
|
+
_takeDraftBundle() {
|
|
246
114
|
if (this.#consumed) {
|
|
247
|
-
throw new Error(
|
|
248
|
-
|
|
249
|
-
if (this.#ref.kind !== "transient" || !this.#transientBytes) {
|
|
250
|
-
throw new Error("Skill.uploadIfChanged: only unstaged transient Skills (built via Skill.fromFiles / Skill.fromPath) can be checked; " +
|
|
251
|
-
"use Skill.fromId(record.id) to reference an already-persisted skill");
|
|
115
|
+
throw new Error("Skill: cannot reuse a consumed Skill in submitRun. Build a fresh Skill via " +
|
|
116
|
+
"Skill.fromPath(...) / Skill.fromFiles(...) per submitRun call.");
|
|
252
117
|
}
|
|
253
|
-
|
|
254
|
-
if (lookup) {
|
|
255
|
-
const existing = await lookup({
|
|
256
|
-
name: this.#ref.name,
|
|
257
|
-
contentHash: this.#ref.contentHash
|
|
258
|
-
});
|
|
259
|
-
if (existing) {
|
|
260
|
-
this.#consumed = true;
|
|
261
|
-
return new Skill({ kind: "workspace", id: existing.id }, existing);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
return this.upload(client);
|
|
265
|
-
}
|
|
266
|
-
/** True for `Skill.fromId(...)` and skills returned by `.upload(...)`. */
|
|
267
|
-
get isWorkspace() {
|
|
268
|
-
return this.#ref.kind === "workspace";
|
|
269
|
-
}
|
|
270
|
-
/** True for `Skill.provider(...)`. */
|
|
271
|
-
get isProvider() {
|
|
272
|
-
return this.#ref.kind === "provider";
|
|
273
|
-
}
|
|
274
|
-
/** True for any transient Skill (unstaged or consumed). */
|
|
275
|
-
get isTransient() {
|
|
276
|
-
return this.#ref.kind === "transient";
|
|
277
|
-
}
|
|
278
|
-
/**
|
|
279
|
-
* True only while the transient Skill still carries bytes and has
|
|
280
|
-
* not been consumed by `.upload(...)`. Unstaged Skills can be passed
|
|
281
|
-
* to `submitRun` or `.upload(client)`; consumed ones cannot.
|
|
282
|
-
*/
|
|
283
|
-
get isUnstaged() {
|
|
284
|
-
return (this.#ref.kind === "transient" &&
|
|
285
|
-
this.#ref.slot === UNSTAGED_SLOT &&
|
|
286
|
-
!this.#consumed &&
|
|
287
|
-
this.#transientBytes !== undefined);
|
|
288
|
-
}
|
|
289
|
-
/** True after a successful `.upload(...)` — using this instance further throws. */
|
|
290
|
-
get isConsumed() {
|
|
291
|
-
return this.#consumed;
|
|
292
|
-
}
|
|
293
|
-
/**
|
|
294
|
-
* Internal: yield the unstaged transient bundle's payload so the
|
|
295
|
-
* client's `submitRun` can build a multipart part. Returns undefined
|
|
296
|
-
* for non-transient or consumed skills. Throws if the instance is
|
|
297
|
-
* marked consumed (a stronger signal than "no bytes").
|
|
298
|
-
*
|
|
299
|
-
* NOT part of the public API — the `_` prefix is a "do not call from
|
|
300
|
-
* user code" marker. Callers within the SDK pass the returned bytes
|
|
301
|
-
* into the multipart body once per `submitRun` invocation.
|
|
302
|
-
*/
|
|
303
|
-
_takeUnstagedBundle() {
|
|
304
|
-
if (this.#consumed) {
|
|
305
|
-
throw new Error(consumedMessage());
|
|
306
|
-
}
|
|
307
|
-
if (!this.isUnstaged) {
|
|
308
|
-
return undefined;
|
|
309
|
-
}
|
|
310
|
-
if (this.#ref.kind !== "transient" || !this.#transientBytes) {
|
|
118
|
+
if (this.#ref.kind !== "draft" || !this.#inlineBytes) {
|
|
311
119
|
return undefined;
|
|
312
120
|
}
|
|
121
|
+
this.#consumed = true;
|
|
313
122
|
return {
|
|
314
123
|
name: this.#ref.name,
|
|
315
|
-
|
|
316
|
-
|
|
124
|
+
contentHash: this.#ref.contentHash,
|
|
125
|
+
bytes: this.#inlineBytes
|
|
317
126
|
};
|
|
318
127
|
}
|
|
319
|
-
/**
|
|
320
|
-
* JSON serialisation guard. Workspace and provider Skills serialise
|
|
321
|
-
* to their `ref`. Unstaged transient Skills throw — the bytes are not
|
|
322
|
-
* in the JSON, so a round-trip would silently drop them. Consumed
|
|
323
|
-
* Skills also throw, to surface the "you forgot to use the returned
|
|
324
|
-
* Skill from `.upload(...)`" mistake at the point it happens.
|
|
325
|
-
*/
|
|
326
128
|
toJSON() {
|
|
327
|
-
if (this.#
|
|
328
|
-
throw new Error(
|
|
329
|
-
|
|
330
|
-
if (this.isUnstaged) {
|
|
331
|
-
throw new Error("Cannot JSON-serialise an unstaged transient Skill — the bytes are not in the JSON. " +
|
|
332
|
-
"Persist via skill.upload(client) and serialise the returned (workspace) Skill, " +
|
|
333
|
-
"or pass the unstaged Skill directly to submitRun without serialising.");
|
|
129
|
+
if (this.#ref.kind === "draft") {
|
|
130
|
+
throw new Error("Skill: draft Skills cannot be JSON-serialised — they only become wire refs when " +
|
|
131
|
+
"client.submitRun uploads the bytes to R2.");
|
|
334
132
|
}
|
|
335
133
|
return this.#ref;
|
|
336
134
|
}
|
|
337
135
|
}
|
|
338
|
-
/** Sentinel slot id used by unstaged transient Skills. */
|
|
339
|
-
const UNSTAGED_SLOT = "(unstaged)";
|
|
340
|
-
function resolveChunkedUploader(client) {
|
|
341
|
-
return client._chunkedUpload;
|
|
342
|
-
}
|
|
343
|
-
function resolveUploader(client) {
|
|
344
|
-
const direct = client._uploadSkillBundle;
|
|
345
|
-
if (typeof direct === "function") {
|
|
346
|
-
return direct.bind(client);
|
|
347
|
-
}
|
|
348
|
-
const nested = client.skills?._uploadSkillBundle;
|
|
349
|
-
if (typeof nested === "function") {
|
|
350
|
-
return nested.bind(client.skills);
|
|
351
|
-
}
|
|
352
|
-
throw new Error("Skill.upload: client argument does not expose an upload entry point — " +
|
|
353
|
-
"pass the AntpathClient instance or its `client.skills`");
|
|
354
|
-
}
|
|
355
|
-
function resolveLookup(client) {
|
|
356
|
-
const nested = client.skills?.findByHash;
|
|
357
|
-
if (typeof nested === "function") {
|
|
358
|
-
return nested.bind(client.skills);
|
|
359
|
-
}
|
|
360
|
-
const direct = client.findByHash;
|
|
361
|
-
if (typeof direct === "function") {
|
|
362
|
-
return direct.bind(client);
|
|
363
|
-
}
|
|
364
|
-
return undefined;
|
|
365
|
-
}
|
|
366
|
-
function consumedMessage() {
|
|
367
|
-
return ("this Skill was already uploaded via skill.upload(client); use the returned Skill or " +
|
|
368
|
-
"Skill.fromId(record.id) for subsequent runs");
|
|
369
|
-
}
|
|
370
136
|
//# sourceMappingURL=skill.js.map
|
package/dist/skill.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill.js","sourceRoot":"","sources":["../src/skill.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,
|
|
1
|
+
{"version":3,"file":"skill.js","sourceRoot":"","sources":["../src/skill.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/dist/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC"}
|
package/docs/cleanup.md
CHANGED
|
@@ -15,4 +15,4 @@ const ref = await client.submitRun(template, {
|
|
|
15
15
|
|
|
16
16
|
The corresponding CLI flag is `--cleanup retain` (default `delete`).
|
|
17
17
|
|
|
18
|
-
A retained session remains visible to Anthropic until the workspace's retention policy reclaims it.
|
|
18
|
+
A retained session remains visible to Anthropic until the workspace's retention policy reclaims it. antpath records `cleanupStatus` (`succeeded` for delete, `retained` for retain, `failed` for crash-stranded resources) and `provider_resources` rows so a future repair operation can recover orphaned resources when needed.
|
package/docs/credentials.md
CHANGED
|
@@ -6,7 +6,7 @@ title: Credentials
|
|
|
6
6
|
|
|
7
7
|
antpath does not store provider keys or MCP credential values across runs.
|
|
8
8
|
|
|
9
|
-
The caller passes a workspace-scoped SDK token and provider key inline on every `submitRun` call.
|
|
9
|
+
The caller passes a workspace-scoped SDK token and provider key inline on every `submitRun` call. antpath vaults the bundle for the lifetime of a single run and destroys it at cleanup. MCP credentials and skill references travel the same way.
|
|
10
10
|
|
|
11
11
|
MVP credential types for MCP auth:
|
|
12
12
|
|
|
@@ -126,7 +126,7 @@ When a Template uses `limited` networking, the platform host must appear in `all
|
|
|
126
126
|
|
|
127
127
|
```ts
|
|
128
128
|
const allowedHosts = buildPlatformAllowedHosts({
|
|
129
|
-
|
|
129
|
+
baseUrl: "https://api.antpath.ai",
|
|
130
130
|
extraHosts: ["api.stripe.com"]
|
|
131
131
|
});
|
|
132
132
|
```
|
package/docs/events.md
CHANGED
|
@@ -4,7 +4,7 @@ title: Events
|
|
|
4
4
|
|
|
5
5
|
# Events
|
|
6
6
|
|
|
7
|
-
Claude Managed Agents sessions run autonomously on Anthropic's infrastructure. They are **non-blocking**: the worker polls the provider session while the agent thinks, calls tools, and emits messages on its own schedule, and persists every captured event to
|
|
7
|
+
Claude Managed Agents sessions run autonomously on Anthropic's infrastructure. They are **non-blocking**: the worker polls the provider session while the agent thinks, calls tools, and emits messages on its own schedule, and persists every captured event to antpath. The SDK and CLI observe the durable event timeline from antpath — there is no in-process tool-approval hook (`permission_policy` is `always_allow`).
|
|
8
8
|
|
|
9
9
|
## Two ways to consume events
|
|
10
10
|
|
|
@@ -15,7 +15,7 @@ const events = await ref.events();
|
|
|
15
15
|
|
|
16
16
|
```ts
|
|
17
17
|
// Stream live: yields each event exactly once, stops when the run reaches
|
|
18
|
-
// a terminal status. Backed by polling the
|
|
18
|
+
// a terminal status. Backed by polling the antpath events endpoint.
|
|
19
19
|
for await (const event of ref.stream({ intervalMs: 1000 })) {
|
|
20
20
|
if (event.type === "agent.message") {
|
|
21
21
|
// ...
|
|
@@ -25,24 +25,24 @@ for await (const event of ref.stream({ intervalMs: 1000 })) {
|
|
|
25
25
|
|
|
26
26
|
> **Transport.** `stream()` polls under the hood — it issues `GET
|
|
27
27
|
> /api/runs/:id/events?since=…` calls at `intervalMs` until the run
|
|
28
|
-
> reaches a terminal status.
|
|
29
|
-
>
|
|
30
|
-
>
|
|
28
|
+
> reaches a terminal status. antpath also exposes an SSE endpoint
|
|
29
|
+
> (`GET /api/runs/:id/events/stream`) that the dashboard UI consumes;
|
|
30
|
+
> an SSE-backed SDK transport is on the public backlog. For
|
|
31
31
|
> latency-sensitive consumers the polling baseline is acceptable down
|
|
32
32
|
> to about 500 ms.
|
|
33
33
|
|
|
34
34
|
The CLI mirrors the same surface:
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
antpath events <run-id> --api-token … [--
|
|
38
|
-
antpath events <run-id> --follow --api-token … [--
|
|
37
|
+
antpath events <run-id> --api-token … [--antpath-url …] # snapshot
|
|
38
|
+
antpath events <run-id> --follow --api-token … [--antpath-url …] # stream until terminal
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
Both surfaces observe the same events. A subscriber attached after `submitRun()` returns replays the events it missed, then continues live.
|
|
42
42
|
|
|
43
43
|
## Event shape
|
|
44
44
|
|
|
45
|
-
Events are typed as the discriminated `RunEvent` union — agent messages, tool uses, tool results, session status transitions, sdk lifecycle events, span events.
|
|
45
|
+
Events are typed as the discriminated `RunEvent` union — agent messages, tool uses, tool results, session status transitions, sdk lifecycle events, span events. antpath records the raw provider payload **after** secret redaction and structural sanitization, so the bytes you see in `event.payload` never contain the Anthropic key, MCP credentials, or proxy bearer that were supplied to `submitRun`.
|
|
46
46
|
|
|
47
47
|
## Typed helpers
|
|
48
48
|
|
package/docs/outputs.md
CHANGED
|
@@ -6,6 +6,8 @@ title: Outputs
|
|
|
6
6
|
|
|
7
7
|
Every run produces durable metadata (status, events, snapshots, cleanup state). File bytes are **opt-in** via the submission's `outputDirs` field. There is a single method, `RunRef.download()`, that returns the whole run — metadata plus opt-in file bytes — as a streaming zip.
|
|
8
8
|
|
|
9
|
+
> Inside the container, the path `/mnt/session/outputs` is also exposed as `$ANTPATH_OUTPUTS` (sourceable from `RUNTIME.env`) and as `runtimeManifest.envVars.ANTPATH_OUTPUTS` on the SDK-side `RunRef`. See [runtime environment](../../../references/runtime-environment.md).
|
|
10
|
+
|
|
9
11
|
## Quickstart
|
|
10
12
|
|
|
11
13
|
```ts
|
package/docs/quickstart.md
CHANGED
|
@@ -13,7 +13,7 @@ import { AntpathClient } from "antpath";
|
|
|
13
13
|
|
|
14
14
|
const client = new AntpathClient({
|
|
15
15
|
apiToken: process.env.ANTPATH_API_TOKEN!
|
|
16
|
-
// baseUrl defaults to https://
|
|
16
|
+
// baseUrl defaults to https://api.antpath.ai — set it for self-hosted deployments.
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
const ref = await client.submitRun({
|
|
@@ -54,7 +54,23 @@ antpath run \
|
|
|
54
54
|
--follow
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
-
For a config-file flow, pass `--config <path>` with a JSON file matching the `Blueprint` shape (`{ model, system?, prompt, skills?, mcpServers?, environment?, cleanup?, proxyEndpoints?, metadata? }`). Both surfaces hit the same
|
|
57
|
+
For a config-file flow, pass `--config <path>` with a JSON file matching the `Blueprint` shape (`{ model, system?, prompt, skills?, mcpServers?, environment?, cleanup?, proxyEndpoints?, metadata? }`). Both surfaces hit the same antpath backend and operate on the same durable run records — pick whichever is most convenient.
|
|
58
|
+
|
|
59
|
+
## Where things go: customer → primitive mapping
|
|
60
|
+
|
|
61
|
+
Every kind of thing you want to ship at run time has exactly one right primitive in the SDK. Reach for the right one rather than rolling your own wrapper.
|
|
62
|
+
|
|
63
|
+
| What you have | Primitive | What it does |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| Non-secret paths or config (`BROLL_STORE`, mode flags) | `environment.envVars` | Mounted as `RUNTIME.env` / `RUNTIME.json`; `__KEY__` substitution in agent-facing markdown; echoed back as `ref.runtimeManifest.envVars` |
|
|
66
|
+
| Upstream HTTPS API keys (TMDB, Brave, Tavily, …) | `ProxyEndpoint` | Credentials live server-side; antpath proxy injects them on outbound calls. The key never enters the container. |
|
|
67
|
+
| MCP server credentials | `secrets.mcpServers` | Anthropic Vault, attached per session |
|
|
68
|
+
| Anthropic API key | `secrets.anthropic.apiKey` | Required on every `submitRun`; per-run vault entry |
|
|
69
|
+
| Non-secret reference data folders (transcripts, persona docs, PDFs) | `File.fromPath('./customer-folder/')` | Mounted under `/mnt/session/uploads/antpath/files/<f_id>/<rel>` and listed in the synthetic first user message |
|
|
70
|
+
| Executable skill code (a `.pyz` wrapper, scripts, prompts) | `Skill.fromPath('./skills/my-skill/')` | Registered with Anthropic's Skills API; auto-discovered by the agent |
|
|
71
|
+
| Agent instructions file | `AgentsMd.fromPath('./AGENTS.md')` | Prepended as the first user turn |
|
|
72
|
+
|
|
73
|
+
For the full design behind `environment.envVars`, the `RUNTIME.{json,env}` mounts, and `__KEY__` substitution, see [`references/runtime-environment.md`](../../../references/runtime-environment.md). For `Skill` / `AgentsMd` / `File` semantics, see [`references/agent-context-uploads.md`](../../../references/agent-context-uploads.md).
|
|
58
74
|
|
|
59
75
|
## Safe retries with `idempotencyKey`
|
|
60
76
|
|
package/docs/skills.md
CHANGED
|
@@ -16,9 +16,7 @@ Skill inputs accepted by the platform:
|
|
|
16
16
|
- workspace skill bundles (persistent, referenced by `skl_*` id);
|
|
17
17
|
- inline-supplied bundles passed directly at `submitRun` — these
|
|
18
18
|
persist on antpath as workspace skills with auto-suffixed names,
|
|
19
|
-
one row per submission (see "Inline supply" below)
|
|
20
|
-
- inline skill content (markdown strings or local files) mounted as
|
|
21
|
-
session resources for legacy `local` / `inline` skill defs.
|
|
19
|
+
one row per submission (see "Inline supply" below).
|
|
22
20
|
|
|
23
21
|
**Routing at session create:** bundles that contain `SKILL.md` at the
|
|
24
22
|
bundle root are registered with Anthropic's Skills API
|
package/docs/templates.md
CHANGED
|
@@ -11,14 +11,15 @@ Allowed `Blueprint` fields:
|
|
|
11
11
|
- `model` — required.
|
|
12
12
|
- `prompt` — required (string or array of strings).
|
|
13
13
|
- `system` — optional system message.
|
|
14
|
-
- `skills` — array of `
|
|
15
|
-
- `mcpServers` — array of `
|
|
16
|
-
- `proxyEndpoints` — array of `
|
|
17
|
-
- `
|
|
18
|
-
- `environment` — packages + networking + `outputDirs`.
|
|
14
|
+
- `skills` — array of `SkillRef` (workspace, provider, or inline).
|
|
15
|
+
- `mcpServers` — array of `McpServerRef` (headers are split into `secrets.mcpServers` server-side).
|
|
16
|
+
- `proxyEndpoints` — array of `PlatformProxyEndpoint`.
|
|
17
|
+
- `environment` — `{ networking?, packages?, envVars? }`. See [runtime environment](../../../references/runtime-environment.md) for the `envVars` surface and the merged `RUNTIME.env` / `RUNTIME.json` mounts.
|
|
19
18
|
- `cleanup` — `{ session: "retain" | "delete" }`.
|
|
20
19
|
- `metadata` — non-secret structured metadata.
|
|
21
20
|
|
|
21
|
+
`agentsMd`, `files`, and `outputDirs` are top-level `submitRun` options, not `Blueprint` fields — they carry bytes / behaviour that don't belong in a reusable credential-free config.
|
|
22
|
+
|
|
22
23
|
Secrets never live in a `Blueprint`. Pass credentials through `submitRun({ ...blueprint, secrets, proxyEndpointAuth })` (SDK) or the equivalent host-mode flags (`--anthropic-api-key`, `--mcp-auth`, `--proxy-auth`).
|
|
23
24
|
|
|
24
25
|
## `defineRun` — typed, reusable factory
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "antpath",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "TypeScript SDK for running autonomous Claude Managed Agents sessions.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
5
6
|
"repository": {
|
|
6
7
|
"type": "git",
|
|
7
8
|
"url": "git+https://github.com/weilueluo/antpath.git"
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export interface RedactedSecret {
|
|
2
|
-
expose(): string;
|
|
3
|
-
toJSON(): string;
|
|
4
|
-
toString(): string;
|
|
5
|
-
}
|
|
6
|
-
export declare function redactedSecret(value: string): RedactedSecret;
|
|
7
|
-
export declare function redactKnownSecrets(input: string, secrets: readonly RedactedSecret[]): string;
|